我经常有一个或多个变量分组的数据,每个组中有几个注册。从数据框架,我希望根据各种标准选择组。
我通常使用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唯一的替代方案来实现这一目标?
答案 0 :(得分:4)
至少在这种情况下,这会得到相同的结果
library(plyr)
dd5 <- ddply(dd,.(group),function(x) x[max(x$mass)<45,])
all(dd4==dd5)
[1] TRUE
答案 1 :(得分: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]
答案 2 :(得分:2)
我意识到您已经特别要求plyr
解决方案,但我想我也会在基础R中分享另一种方法,不涉及您的多步骤方法:
dd[as.logical(ave(dd$mass, dd$group, FUN = function(x) max(x) < 45)), ]
在处理R中的组时,ave
函数通常很方便。在这里,我创建了一个逻辑向量,并根据“TRUE
”值的索引进行了子集化。