5

我经常有按一个或多个变量分组的数据,每组中有几个注册。从数据框中,我希望根据各种标准选择组。

我通常使用 split-sapply-rbind 方法,其中我使用逻辑向量从列表中提取元素。

这是一个小例子。我从一个具有一个分组变量('group')的数据框开始,我希望选择最大质量小于 45 的组:

dd <- data.frame(group = rep(letters[1:3], each = 5), 
                 mass = c(rnorm(5, 30), rnorm(5, 50), 
                          rnorm(5, 40)))
    dd2 <- split(x = dd, f = dd$group)
    dd3 <- dd2[sapply(dd2, function(x) max(x$mass) < 45)]
    dd4 <- do.call(rbind, dd3)

我刚刚开始使用 plyr,现在我想知道:
是否有一个 plyr-only 替代方案来实现这一目标?

4

3 回答 3

4

至少在这种情况下,这给出了相同的结果

library(plyr)
dd5 <- ddply(dd,.(group),function(x) x[max(x$mass)<45,])

all(dd4==dd5)
[1] TRUE
于 2012-12-07T13:54:54.767 回答
3

这是一个用于编码优雅的 data.table 解决方案

library(data.table)
DT <- data.table(dd)

DT[,if(max(mass) < 45){.SD},by=group]
    group     mass
 1:     a 28.80426
 2:     a 31.31232
 3:     a 29.47599
 4:     a 30.35425
 5:     a 29.92833
 6:     c 40.11349
 7:     c 40.17431
 8:     c 39.94652
 9:     c 39.57524
10:     c 40.20791

也许稍微复杂一些

new <- (DT[,index := max(mass) < 45,by=group][force(index)])[,index:=NULL]
于 2012-12-09T22:40:22.943 回答
2

我意识到您已经特别要求提供plyr解决方案,但我想我也会在不涉及您的多步骤方法的基础 R 中分享一种替代方法:

dd[as.logical(ave(dd$mass, dd$group, FUN = function(x) max(x) < 45)), ]

在处理 R 中的组时,该ave函数通常很方便。在这里,我创建了一个逻辑向量,并根据 " TRUE" 值的索引进行子集化。

于 2012-12-07T15:19:18.923 回答