R适用于动态参数

时间:2016-08-30 11:30:45

标签: r loops dynamic arguments apply

我只是想知道是否可以使用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中很容易实现,但我会尝试申请,看它是否是相当快的解决方案。

感谢您的任何建议!

巴特

2 个答案:

答案 0 :(得分:0)

如果我理解正确的话,下面的代码是您问题的可能解决方案。正如@jogo在您的问题的评论中提到的,深度分配函数<<-会导致副作用,这可能是危险的。为了使代码正常工作,我应用了a的索引而不是元素。

循环在R中得到了糟糕的说唱但他们并不总是坏事。在这种情况下,我提出的sapply适合您的解决方案实际上比竞争循环解决方案慢(用microbenchmark测量),并且循环具有不依赖于副作用的优点。 / p>

sapply solution

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

loop vs sapply

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)

这可能非常复杂,具体取决于您正在处理的功能。因此,在您想要投资的时间与简化计算机将获得的速度之间存在权衡。