首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >访问lapply/sapply中以前的元素

访问lapply/sapply中以前的元素
EN

Stack Overflow用户
提问于 2015-07-24 20:14:18
回答 2查看 2.1K关注 0票数 6

我正在尝试用sapply函数替换for循环。在循环中,我做了一些优化,因此下一个循环需要一个优化的结果。

我知道了如何使用sapply来运行优化,但问题是我需要从sapply中访问以前的结果。

以下只是我想要实现的一个随机示例。

代码语言:javascript
复制
sapply(1:4, function(y){
  r<-y
  if(y!=1){z<-r[y-1]}
  else{z<-9}
  return(z)
  })

[1,]    9    2   NA   NA

我希望得到的结果是:

代码语言:javascript
复制
[1,]    9    1    2   3

我做错了什么?或者,没有任何方法可以在sapply中访问以前的迭代结果

EN

回答 2

Stack Overflow用户

发布于 2015-07-25 04:09:45

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

代码语言:javascript
复制
f    = function(x) x^2
g    = function(x) abs(x)+rnorm(1)
yvec = 1:4

以下是@Andrie提到的Reduce方法:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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

结果是一样的,所以Reduce只是隐藏了这个循环,正如@Roland所断言的那样。

票数 13
EN

Stack Overflow用户

发布于 2015-07-24 20:19:47

您不能使用apply函数系列访问以前的结果。它们是for循环的包装器,所以如果这是您想要的,就没有理由显式地避免循环。

对于你的问题“我做错了什么?”使用你的函数:

代码语言:javascript
复制
sapply(1:4, function(y){
  r<-y
  if(y!=1){z<-r[y-1]}
  else{z<-9}
  return(z)
  })

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

当传递1时,它转到else语句,并为z分配9。当传递2时,它将转到表达式r[y-1]。在该迭代中,r等于2y也是如此。因此,它等同于简化为2[1]2[2-1]。它可以被理解为“向量答案的第一个元素。答案是2”。

在下一轮,r等于3y也是如此。该表达式现在为3[3-1]。简化为3[2]。这是一个问题,因为向量3的第二个元素是什么?没有,它只有一个元素。因此返回NA。同样的效果也会发生在循环的其余部分。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31610303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档