【问题标题】:R:create new column and value using lapply & apply nested on data.frame list, wrong outputR:使用 lapply 创建新列和值并应用嵌套在 data.frame 列表中,输出错误
【发布时间】:2014-02-03 17:59:07
【问题描述】:

我有一个数据框列表(这里以 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"}
      }
    )

}
)

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

【问题讨论】:

    标签: r dataframe apply


    【解决方案1】:

    您的方法存在一些问题。第一个是您正在从最里面的应用修改dfx,但是您使用简单的&lt;- 运算符而不是&lt;&lt;- 运算符来进行修改。前一个运算符不会影响函数范围之外的内容。我也不提倡使用&lt;&lt;-(请参阅此处的解决方案以获取替代方案)。

    您遇到的另一个问题是您没有指定要在apply 中更新dfx 的哪一行,所以即使您有&lt;&lt;-,每一行都会更新,您最终会得到最后的值是上次测试比较产生的任何值。

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

    在这里,我们将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,以便跟踪行号。同样,我不推荐这种方法,但在这里是为了解释。

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2019-11-28
        • 2018-11-19
        • 1970-01-01
        • 2014-01-21
        • 1970-01-01
        • 2017-11-23
        • 1970-01-01
        • 2020-10-29
        • 1970-01-01
        相关资源
        最近更新 更多