Pouvez-vous utiliser la fonction lapply () pour modifier la valeur d'entrée?

StackOverflow https://stackoverflow.com/questions/1559724

  •  21-09-2019
  •  | 
  •  

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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top