7
votes

Effectuer une opération sur un vecteur en utilisant la valeur précédente après une valeur initiale

Dans Excel, il est facile d'effectuer un calcul sur une cellule précédente en faisant référence à une cellule antérieure. Par exemple, à partir d'une valeur initiale de 100 (étape = 0), chaque étape suivante serait 0,9 * Précédent + 9 code> en faisant glisser la barre de formule vers le bas de la première cellule (étape = 1). Les 10 prochaines étapes ressembleraient à:

#for loop.  This works
value <- 100   #Initial value
for(i in 2:11) {
  current <- 0.9 * value[i-1] + 9
  value <- append(value, current)
}
cbind(step = 0:10, value)  #Prints the example output shown above

r

1 commentaires

N'utilisez pas append . Préallocate valeur à la taille finale et assignez à ses éléments. Cultiver un objet est l'une des opérations les plus lentes que vous puissiez faire.


3 Réponses :


9
votes

Utilisez nos connaissances sur le Série géométrique .

i <- 0:10
0.9 ^ i * 100 + 9 * (0.9 ^ i - 1) / (0.9 - 1)
#[1] 100.00000  99.00000  98.10000  97.29000  96.56100  95.90490  95.31441  94.78297  94.30467  93.87420  93.48678


1 commentaires

Grande réponse (+1) @roland! J'ai choisi la réponse de @ Walts car il est plus flexible, comme dans les cas où les constantes sont en fait des variables elles-mêmes.



13
votes

On dirait que vous recherchez un moyen de faire des calculs récursifs dans R. Base R a deux façons de faire cela qui diffèrent par la forme de la fonction utilisée pour faire la réursion. Les deux méthodes pourraient être utilisées pour votre exemple.

réduire peut être utilisé avec des équations de récursivité du formulaire V [i + 1] = fonction (V [i], x [i]) v est le vecteur calculé et x un vecteur d'entrée; C'est-à-dire que la sortie i + 1 dépend uniquement des valeurs I Th des vecteurs calculés et d'entrée et le calcul effectué par fonction (v, x) peut être non linéaire. Pour vous, ce cas, ce serait xxx

filtre est utilisé avec des équations de récursivité du formulaire y [i + 1] = x [ i] + filtre [1] * y [i-1] + ... + filtre [p] * y [IP] y est le vecteur calculé et x un vecteur d'entrée; C'est-à-dire que la sortie peut dépendre linéairement sur des valeurs décalées du vecteur calculé ainsi que la valeur i-th du vecteur d'entrée. Pour votre cas, ce serait: xxx

pour les deux fonctions, la longueur de la sortie est donnée par la longueur du vecteur d'entrée x . de
Ces deux approches donnent à votre résultat.


0 commentaires

0
votes

Vous pouvez également utiliser Purrr :: accumuler : xxx

.init est la valeur initiale et il y a aussi l'argument < code> .dir si vous souhaitez contrôler la direction ("Transférer" est la valeur par défaut)


0 commentaires