【问题标题】:differences between lapply(list) and "for"-looplapply(list) 和“for”循环之间的区别
【发布时间】:2015-09-14 07:00:37
【问题描述】:

最近我写了一段代码,但表现不如预期。 在两个数据帧 df1、df2 的循环中,我尝试在矩阵“a”中收集数据...:

df1=data.frame(x=c(1,2),y=c(10,20))
df2=data.frame(x=c(4,5),y=c(40,50))
dlist <- list(df1,df2)

a <- c(0,"...creation...")
a <- rbind(a, c(0,"rbind test OK"))

lapply(dlist, function(d) {
   print(paste("x",d$x[1]))
   a <- rbind(a, c(d$x[1],"data copied"))
   })

a <- rbind(a, c(0,"rbind test 2 OK"))

在执行这些行之后检查“a”会产生

a
  [,1] [,2]             
a "0"  "...creation..." 
  "0"  "rbind test OK"  
  "0"  "rbind test 2 OK"

也就是说,lapply-loop里面的rbind-statement没有被执行。

预期输出是:

a 
  [,1] [,2] 
a "0"  "...creation..." 
  "0"  "rbind test OK" 
  "1"  "data copied" 
  "4"  "data copied" 
  "0"  "rbind test 2 OK"

这是为什么呢?

【问题讨论】:

  • 一个区别是 for 循环使用与调用它的环境相同的环境。 lapply(和其他类似的函数)使用自己的环境,就像其他函数一样。这意味着您在lapply() 函数中定义的a 与您之前定义的a 不同。如果您想了解更多信息,请提供预期输出示例
  • 预期输出将是 > a [,1] [,2] a "0" "...creation..." "0" "rbind test OK" "1" "data compatible" "4" "数据复制" "0" "rbind test 2 OK"
  • 请编辑您的问题以包含预期的输出。

标签: r


【解决方案1】:

您可以使用运算符&lt;&lt;- 修改循环外部的环境,但这是一种非常不恰当的命令式编程反射:

lapply(dlist, function(d) {
   print(paste("x",d$x[1]))
   a <<- rbind(a, c(d$x[1],"data copied"))
})

正确的方法是:

res = do.call(rbind, lapply(dlist, function(d) c(d$x[1],"data copied")))

a = rbind(a, res, c(0,"rbind test 2 OK"))

#  [,1] [,2]             
#a "0"  "...creation..."  
#  "0"  "rbind test OK"  
#  "1"  "data copied"    
#  "4"  "data copied"    
#  "0"  "rbind test 2 OK"

【讨论】:

    猜你喜欢
    • 2016-08-02
    • 2019-01-11
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    相关资源
    最近更新 更多