以lapply/sapply访问前面的元素

der*_*epe 5 r lapply sapply

我试图for用一个sapply函数替换一个循环.在循环内部我做了一些优化,因此需要为下一个循环进行一次优化的结果.

我想出了如何使用它sapply来运行优化,但问题是我需要从内部访问以前的结果sapply.

以下只是我试图实现的一个随机例子.

sapply(1:4, function(y){
  r<-y
  if(y!=1){z<-r[y-1]}
  else{z<-9}
  return(z)
  })

[1,]    9    2   NA   NA
Run Code Online (Sandbox Code Playgroud)

我期望得到的是:

[1,]    9    1    2   3
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?或者有没有办法访问以前的迭代结果sapply

Fra*_*ank 13

以下是一个可能更接近OP用例的示例:

f    = function(x) x^2
g    = function(x) abs(x)+rnorm(1)
yvec = 1:4
Run Code Online (Sandbox Code Playgroud)

这是Reduce@Andrie提到的方法:

set.seed(1)
Reduce(function(z,y) if (is.na(z)) f(y) else g(z), yvec,init=NA_real_,accumulate=TRUE)[-1]
# [1]  1.0000000  0.3735462  0.5571895 -0.2784391
Run Code Online (Sandbox Code Playgroud)

这是一个每个人都会使用的常识循环(由@digEmAll提到):

set.seed(1)
res <- rep(NA_real_,length(yvec))
for (i in seq_along(yvec)) res[i] = if (i==1) f(yvec[i]) else g(res[i-1])
res
# [1]  1.0000000  0.3735462  0.5571895 -0.2784391
Run Code Online (Sandbox Code Playgroud)

结果是一样的,所以,Reduce只是隐藏循环,正如@Roland所声称的那样.


Pie*_*une 5

您无法使用apply系列函数访问以前的结果.它们是for循环的包装器,因此没有理由明确地避免循环,如果这就是你所追求的.

对于你的问题"我做错了什么?".有了你的功能:

sapply(1:4, function(y){
  r<-y
  if(y!=1){z<-r[y-1]}
  else{z<-9}
  return(z)
  })
Run Code Online (Sandbox Code Playgroud)

在表达式中r[y-1],NA是在前两个循环之后产生的.

1被通过,它进入else声明和z分配9.当2传递时,它转到表达式r[y-1].在那个迭代r中等于2,等等y.所以它相当于2[2-1],简化为2[1].这可以被解读为"向量的第一个元素2.答案是2.

在下一轮,r等于3,等等y.表达式现在3[3-1].简化为3[2].这是一个问题,因为矢量的第二个元素是3什么?没有,它只有一个元素.所以NA归来了.对于循环的其余部分也会发生同样的效果.

  • 你没有解决"我需要从问题的sapply"部分访问以前的结果.想象一下,结果是一个随机过程,在这种情况下,你不能像你提出的那样重新计算结果. (3认同)