【问题标题】:How to split a list of data.frame and apply a function to one column?如何拆分 data.frame 列表并将函数应用于一列?
【发布时间】:2013-01-27 14:18:26
【问题描述】:

我有一个关于应用函数的小问题。 例如我有:

l <- list(a = data.frame(A1=rep(10,5),B1=c(1,1,1,2,2),C1=c(5,10,20,7,30)),
          b = data.frame(A1=rep(20,5),B1=c(3,3,4,4,4),C1=c(3,5,10,20,30)))

我想为每个 B1 找到一个最小 C1。结果应该是

$a
  A1 B1 C1
  10  1  5
  10  2  7

$b
  A1 B1 C1
  20  3  3
  20  4  10

我知道如何使用 'for' 来实现,但使用 'lapply' 必须是一种更简单的方式,但我无法让它发挥作用。

请帮忙

【问题讨论】:

    标签: r list dataframe lapply


    【解决方案1】:

    我最近屈服于 data.table 包的警报声及其多功能性和速度的组合来执行此类操作,我提交了另一个解决方案:

    library(data.table)
    lapply(l, function(dat) {
        data.table(dat, key="B1,C1")[list(unique(B1)), mult="first"]
    })
    

    如果保留原始列顺序很重要,出于某种原因,data.table() 调用可能会被 setcolorder(..., names(dat)) 包装。

    【讨论】:

      【解决方案2】:

      您也可以尝试使用 plyr/reshape2 工具箱中的 llply + dcast:

      library(reshape2)
      library(plyr)
      
          l <- list(a = data.frame(A1=rep(10,5),B1=c(1,1,1,2,2),C1=c(5,10,20,7,30)),
                    b = data.frame(A1=rep(20,5),B1=c(3,3,4,4,4),C1=c(3,5,10,20,30)))
      
          llply(l, function (x) {dcast (x, A1+B1~., value.var="C1", min)})
      

      【讨论】:

        【解决方案3】:

        这是另一种与您想要的输出相匹配的方法:

        lapply(l, function(x) {
          temp <- ave(x[["C1"]], x["B1"], FUN = min)
          x[x[["C1"]] == temp, ]
        })
        # $a
        #   A1 B1 C1
        # 1 10  1  5
        # 4 10  2  7
        # 
        # $b
        #   A1 B1 C1
        # 1 20  3  3
        # 3 20  4 10
        

        【讨论】:

        • 这正是我想要的,非常感谢。我不知道这种 ave 利用率
        【解决方案4】:

        lapplytapply 结合起来怎么样:

        lapply(l, function(i) tapply(i$C1, i$B1, min))
        $a
        1 2 
        5 7 
        
        $b
        3  4 
        3 10 
        

        考虑多个操作的技巧是将任务拆分为多个位。所以,

        1. 每个B1 的最小C1。我们如何为单个数据框做到这一点?

          i = l[[1]]
          tapply(i$C1, i$B1, min)
          
        2. 列表的每个元素?只需使用lapply

          lapply(l, function(i) tapply(i$C1, i$B1, min))
          

        如果您无法执行第 1 步,您将无法管理第 2 步。

        【讨论】:

          猜你喜欢
          • 2015-01-18
          • 2019-05-09
          • 1970-01-01
          • 2015-02-23
          • 1970-01-01
          • 2018-06-29
          • 1970-01-01
          • 2018-03-29
          • 1970-01-01
          相关资源
          最近更新 更多