你可以使用lapply()函数来改变输入的值吗?

时间:2009-10-13 11:47:32

标签: r loops lapply

我想知道是否可以使用lapply()函数来改变输入的值,类似于:

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

我正在寻找类似于for()循环的东西,但是使用了lapply()基础结构。我无法得到rapply()来做这件事。

原因是“真实”a2函数是一个困难的函数,只有在a1 [i-1]的值满足某些条件时才需要进行评估。

重新措辞:所以我试图用lapply()类型的东西替换下面代码中的for():

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

R邮件列表已建议查看Reduce()函数....如:

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

给出与cumprod(a1)相同的结果......但是比循环更慢:

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 
> 

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

编辑:在您澄清之后:不,我不相信您可以使用apply函数来递归地执行某些操作。应用函数的整个要点是它同时应用于向量/矩阵。

您可能还想look at this related question on stackoverflow

我的老回答:

试试这个:

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

for循环不同,您需要在lapply内传递对所需内容的引用。返回也是一个列表,因此您需要将其转换回您想要的任何形式。

您可能还想查看plyr包,以便轻松地执行此类操作。

除此之外,您可以在没有循环的情况下进行操作:

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

换句话说,这些陈述完全等同:

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

但是第一个版本更好,因为它没有迭代。