Can you use the lapply () function to change the value of the input?

I was wondering if the lapply () function could be used to change the value of an input, similarly:

a1<-runif(100)
a2<-function(i){
a1[i]<-a1[i-1]*a1[i];a1[i]
}
a3<-lapply(2:100,a2)

      

I am looking for something similar to a for () loop but using the lapply () framework. I was unable to get rapply () to do this.

The reason is that the "real" function a2 is a complex function that needs to be evaluated only if the value of a1 [i-1] meets some criteria.

re-phrasing: so I'm trying to replace for () in the code below with an application like lapply ():

    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))

      

The R mailing list recommends looking at the Reduce () function ... as in:

a1<-runif(100)
cadd<-function(x) Reduce("*", x, accumulate = TRUE)
cadd(a1)

      

which gives the same result as cumprod (a1) ... but even slower than a loop:

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 
> 

      

Any idea?

+2


source to share


1 answer


Edit: After your clarification: no, I don't believe you can use the apply function to do something recursively. The whole point of an applicable function is that it is applied to a vector / matrix at the same time.

You can also fooobar.com/questions/1718567 / ... .

My old answer:

Try the following:

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))

      

Unlike a loop for

, you need to pass a reference to whatever you need to lapply

. The return is also a list, so you need to return it back to whatever form you want.



You can also look at the plyr package for easy ways to do this.

Alternatively, you can do your work without a loop:

a3 <- a1[-length(a1)] * a1[-1]

      

In other words, these statements are completely equivalent:

> all((a1[-length(a1)] * a1[-1]) == as.numeric(lapply(2:100, a2, a1=a1)))
[1] TRUE

      

But the first version is preferable because it has no iterations.

+2


source







All Articles