R:使用lapply&创建新的列和值。应用嵌套在data.frame列表上,输出错误

时间:2014-02-03 17:59:08

标签: r dataframe apply

我有一个数据框列表(这里以2为例)。

df1 <- read.table(text= "var,X2x,X4x,X6x
101337,4.631833,4.4547,11.097333
345754,3.727433,10.8560,10.536600" ,header=TRUE, sep=",")

 df2 <- read.table(text= "var,X2x,X4x,X6x
101337,5.631833,10.4547,11.097333
345754,5.727433,12.8560,10.536600" ,header=TRUE, sep=",")

dflist <- list(df1=df1, df2=df2)

我想使用lapply来浏览每个data.frame并使用apply进行简单的比较(即检查第二列的值是否大于第三列),给定结果,添加一个新的带有标记的列(在示例中,然后新列称为“因子”。)

我差不多了,但我的脚本输出错误,返回了一个向量列表,而不是带有添加列的data.frames列表。

这是代码:

dfL <- lapply(dflist,function(dfx) {
        apply(dfx,1, function(df) { if(df[3] < (df[4] )) {
      dfx$factor<-"nonNA"} else {dfx$factor<-"NA"}
      }
    )

}
)

请你解释一下我做错了什么?

2 个答案:

答案 0 :(得分:4)

您的方法存在一些问题。首先,您要从最里面的应用修改dfx,但是您使用简单的<-运算符代替<<-运算符。前一个运算符不会影响函数范围之外的事物。我也不主张使用<<-(请参阅此处的替代方案)。

您遇到的另一个问题是,您没有指定要在dfx内更新apply的哪一行,所以即使您有<<-每一行都会更新,而您无论最后的测试比较是什么,最终的结果都是最终的。

最后,您要在apply中返回dfx的结果,而不是修改后的lapply

在这里,我们将transform函数应用于每个数据框,以根据数据框中第3和第4列的值(此处按名称引用)添加factor列。请注意我是如何使用ifelse来避免内部apply

lapply(dflist, transform, factor=ifelse(X4x < X6x, "nonNA", "NA"))

# $df1
# var      X2x     X4x      X6x factor
# 1 101337 4.631833  4.4547 11.09733  nonNA
# 2 345754 3.727433 10.8560 10.53660     NA
# 
# $df2
# var      X2x     X4x      X6x factor
# 1 101337 5.631833 10.4547 11.09733  nonNA
# 2 345754 5.727433 12.8560 10.53660     NA

这是一个不必要的变化,它更接近你想要做的事情,比较/对比,希望你能更清楚地看到为什么你的工作不起作用:

lapply(dflist, 
  function(dfx) {
    dfx$factor <- ""
    lapply(1:nrow(dfx), 
      function(row.id) {
        dfx[row.id, "factor"] <<- 
          if(dfx[row.id, 3] < dfx[row.id, 4]) "nonNA" else "NA"
    } )
    dfx
} )

注意我在内循环中lapply而不是apply的方式,以便我可以跟踪行号。同样,我不推荐这种方法,但它是出于解释目的。

答案 1 :(得分:2)

您可以尝试这样的事情。对于矢量化操作,您不需要apply

lapply(dflist, function(x){
  x$grp <- "not smaller"
  x$grp[x[ , 3] < x[ , 4]] <- "smaller"
  x
})

# $df1
#     var      X2x     X4x      X6x         grp
# 1 101337 4.631833  4.4547 11.09733     smaller
# 2 345754 3.727433 10.8560 10.53660 not smaller
# 
# $df2
#      var      X2x     X4x      X6x         grp
# 1 101337 5.631833 10.4547 11.09733     smaller
# 2 345754 5.727433 12.8560 10.53660 not smaller