Pouvez-vous utiliser la fonction lapply () pour modifier la valeur d'entrée?
Question
Je me demande s'il est possible d'utiliser la fonction lapply () pour modifier la valeur de l'entrée, similaire à:
a1<-runif(100)
a2<-function(i){
a1[i]<-a1[i-1]*a1[i];a1[i]
}
a3<-lapply(2:100,a2)
Je cherche quelque chose de semblable à une boucle (), mais en utilisant l'infrastructure lapply (). Je ne l'ai pas été en mesure d'obtenir rapply () pour le faire.
La raison en est que la fonction « réelle » a2 est une fonction difficile qui n'a besoin que d'évaluer si la valeur de a1 [i-1] répond à certains critères.
re-phrasé: donc je suis en train de remplacer le for () dans le code ci-dessous par un (lapply) - chose du type:
a1<-runif(100)
a2<-function(i, a1){
a1[i]<-a1[i-1]*2
a1[i]
}
a3<-as.numeric(lapply(2:100, a2, a1=a1))
#compare the output of a3 with that of a1 after the recursive loop
a2<-a1 #saved for comparison
for(i in 2:length(a1)){
a1[i]<-a1[i-1]*2
}
cbind(a1[2:100],a3)
#actually this is would be like writting a lapply() version of the cumprod() function
cbind(a1,cumprod(a2))
La R liste de diffusion a conseillé à la recherche vers la fonction Réduire () .... comme dans:
a1<-runif(100)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
cadd(a1)
ce qui donne le même résultat que cumprod (a1) ... mais il est encore plus lent que la boucle:
a1<-runif(100000)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
looop<-function(a1){
j<-length(a1)
for(i in 2:j){
a1[i]<-a1[i-1]*a1[i]
}
a1
}
> system.time(cadd(a1))
user system elapsed
1.344 0.004 1.353
> system.time(cumprod(a1))
user system elapsed
0.004 0.000 0.002
> system.time(loop(a1))
user system elapsed
0.772 0.000 0.775
>
Une idée?
La solution
Edit: Après votre clarification: non, je ne crois pas que vous pouvez utiliser une fonction de transformation pour faire quelque chose comme ça récursive. Le point d'appliquer une fonction entière est qu'il applique à travers le vecteur / matrice en même temps.
Vous pouvez également regarder cette question connexe sur stackoverflow .
Ma vieille réponse:
Essayez ceci:
a1<-runif(100)
a2<-function(i, a1){
a1[i]<-a1[i-1]*a1[i]
a1[i]
}
a3 <- as.numeric(lapply(2:100, a2, a1=a1))
Contrairement à une boucle de for
, vous devez passer dans une référence à tout ce que vous avez besoin dans un lapply
. Le retour est également une liste, vous devez donc jeter de nouveau dans quelque forme que vous voulez.
Vous pouvez également regarder le paquet plyr des moyens faciles à faire ce genre de chose.
Au-delà, vous pouvez faire votre opération sans une boucle:
a3 <- a1[-length(a1)] * a1[-1]
En d'autres termes, ces déclarations sont complètement équivalentes:
> all((a1[-length(a1)] * a1[-1]) == as.numeric(lapply(2:100, a2, a1=a1)))
[1] TRUE
Mais la première version est préférable car il n'a pas d'itérations.