我只是想知道是否可以使用apply函数,以便在使用下一个i索引之前刷新其中一个参数。让我举一个例子:
我有一个简单的10元素向量:
a<-c(1,rep(NA,9))
定义一个替换a的第i个元素的函数,其总和为2和前一个:
fun<-function(i,vec){
vec[i]<-2+cumsum(vec)[i-1]
a<<-vec
}
现在我想使用sapply,f.e。
sapply(2:10,fun,vec=a)
因此我得到了矢量1,3,...19
。
我知道在for-loop中很容易实现,但我会尝试申请,看它是否是相当快的解决方案。
感谢您的任何建议!
巴特
答案 0 :(得分:0)
如果我理解正确的话,下面的代码是您问题的可能解决方案。正如@jogo在您的问题的评论中提到的,深度分配函数<<-
会导致副作用,这可能是危险的。为了使代码正常工作,我应用了a
的索引而不是元素。
循环在R中得到了糟糕的说唱但他们并不总是坏事。在这种情况下,我提出的sapply
适合您的解决方案实际上比竞争循环解决方案慢(用microbenchmark
测量),并且循环具有不依赖于副作用的优点。 / p>
a <- c(1,rep(NA,9))
fun<-function(i,vec){
a[i] <<- 2+cumsum(vec)[i-1]
}
sapply(seq_along(a)[-1], function(i) fun(i,a))
loopSoln <- function() {
a <- c(1,rep(NA,9))
for(i in seq_along(a)[-1]) {
a[i] <- 2+cumsum(a)[i-1]
}
return(a)
}
fun<-function(i,vec){
a[i] <<- 2+cumsum(vec)[i-1]
}
applySoln <- function() {
a <- c(1,rep(NA,9))
sapply(seq_along(a)[-1], function(i) fun(i,a))
return(a)
}
microbenchmark::microbenchmark(loopSoln(), applySoln())
Unit: microseconds
expr min lq mean median uq max neval
loopSoln() 28.915 30.6960 34.36206 32.5115 33.9085 99.525 100
applySoln() 77.664 80.9815 88.13986 83.1465 85.3815 207.569 100
答案 1 :(得分:0)
据我所知,你不能使用* apply系列进行这种计算。
编辑:Ops,刚看到答案。让我重新说一句,如果没有全球性的分配'&lt;&lt; - ',就不能这样做原因是* apply需要预先输入所有输入值。像你这样的任何递归函数你没有转换就无法工作。
我看到了一种添加* apply函数并使其更快的方法,但是你需要一些数学运算:你可以尝试解决方程式的递归问题。
使用给出的示例,我们有。
vec[i] = 2 + cumsum(vec[i-1])
数学上相当于:
vec[i]= 2 +2 +cumsum(vec[i-2])+cumsum(vec[i-2])
根据这个推理,我们得到:
vec[i]=2*i +vec[1]*i
可以在lapply中使用:
non.rec <- function(x,initial) {2*x+initial*x}
lapply(2:10,non.rec,initial=1)
这可能非常复杂,具体取决于您正在处理的功能。因此,在您想要投资的时间与简化计算机将获得的速度之间存在权衡。