2015-09-14 102 views
1

最近我写了一段代码,其行为并不像预期的那样。 在一个循环超过两dataframes DF1,DF2我试图收集在一个矩阵数据“一” ...:lapply(list)和“for”的区别-loop

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 
    [,1] [,2]    
a "0" "...creation..." 
    "0" "rbind test OK" 
    "0" "rbind test 2 OK" 

也就是说,lapply循环内的rbind语句没有执行。

预期成果是:

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

这是为什么?

+0

一个区别是for循环在调用时使用相同的环境; lapply(和其他类似的功能)使用他们自己的环境,就像其他功能一样。这意味着您在'lapply()'函数中定义的'a'与您之前定义的'a'不同。请提供一个预期输出的例子,如果你想要更多的信息 –

+0

预期的输出将是 > a [,1] [,2] a“0”“...创建...” “0”“rbind测试OK“ ”1“”数据复制“ ”4“”数据复制“ ”0“”rbind test 2 OK“ – JCR

+0

请修改您的问题以包含预期输出。 – 2015-09-14 07:21:27

回答

0

您可以修改环境与运营商<<-循环,但是这是一个非常不适当的命令式编程reflexe:

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"