【问题标题】:Can you use the lapply() function to alter the value of input?你可以使用 lapply() 函数来改变输入的值吗?
【发布时间】:2010-12-06 07:03:20
【问题描述】:

我想知道是否可以使用 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 
> 

有什么想法吗?

【问题讨论】:

  • 我不认为我遵循你想做的事。 a1[i](您正在计算的内容)是否取决于 a1[i-1]?如果是这样,我认为最好使用循环。如果没有,最好对向量进行子集化并在该部分执行函数。
  • 在上面的最后一行中这些是否应该等效:cbind(a1,cumprod(a2))?据我所知,它们不匹配。
  • Shane:这就是问题所在: looop() 函数(见帖子)给出了与 cumprod 相同的结果......但 lapply() 版本没有。我想递归地应用一个函数(比乘法更复杂),它使用向量上的先前评估的值......并且找不到避免循环的方法
  • 我实际上指的是你的循环输出。
  • 你的目标是加快你的程序,还是让它更具可读性?如果你想加快速度,你的主要选择是使用 C/C++。请参阅我在下面链接的关于 R 中递归序列的另一个问题。

标签: r loops lapply


【解决方案1】:

编辑:在您澄清之后:不,我不相信您可以使用 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 中传递对您需要的任何内容的引用。 return 也是一个列表,所以你需要把它转换成你想要的任何形式。

您可能还想查看 plyr 包,了解执行此类操作的简单方法。

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

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

换句话说,这些语句是完全等价的:

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

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

【讨论】:

    猜你喜欢
    • 2016-05-28
    • 2020-03-17
    • 2012-11-26
    • 2018-08-10
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多