5

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

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”必须是一种更简单的方法,但我无法让它发挥作用。

请帮忙

4

4 回答 4

4

lapply结合and怎么样tapply

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

$b
3  4 
3 10 

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

  1. 每个. C1_ B1我们如何为单个数据框执行此操作?

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

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

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

于 2013-02-12T10:00:39.020 回答
3

最近屈服于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)).

于 2013-03-03T23:44:00.247 回答
2

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

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
于 2013-02-12T12:15:40.590 回答
0

您也可以从 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)})
于 2013-03-03T22:09:18.757 回答