lapply(list)和" for" -loop之间的差异

时间:2015-09-14 07:00:38

标签: r

最近我写了一段不符合预期的代码。 在两个数据帧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"))

检查&#34; a&#34;执行这些行后产生

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"

为什么?

1 个答案:

答案 0 :(得分:0)

您可以使用运算符<<-修改环境外部环境,但这是一个非常不合适的命令式编程反射:

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"