为每个组设置前n行的数据框,并按变量排序

时间:2011-05-20 17:38:40

标签: r group-by data.table plyr

我想为n行设置数据框的子集,这些行按变量分组,并按另一个变量降序排序。这将是一个明确的例子:

    d1 <- data.frame(Gender = c("M", "M", "F", "F", "M", "M", "F", 
  "F"), Age = c(15, 38, 17, 35, 26, 24, 20, 26))

我想为每个性别获得2行,这些行按年龄递减排序。所需的输出是:

Gender  Age  
F   35  
F   26  
M   38  
M   26  

我在这里寻找订单,排序和其他解决方案,但找不到合适的解决方案来解决这个问题。我感谢您的帮助。

6 个答案:

答案 0 :(得分:13)

使用ddply()

中的plyr的一个解决方案
require(plyr)
ddply(d1, "Gender", function(x) head(x[order(x$Age, decreasing = TRUE) , ], 2))

答案 1 :(得分:6)

使用data.table包

require(data.table)
dt1<-data.table(d1)# to speedup you can add setkey(dt1,Gender)
dt1[,.SD[order(Age,decreasing=TRUE)[1:2]],by=Gender]

答案 2 :(得分:1)

我确信有更好的答案,但这是一种方式:

require(plyr)
ddply(d1, c("Gender", "-Age"))[c(1:2, 5:6),-1]

如果您的数据框大于此处提供的数据框,并且不想直观地检查要选择的行,请使用:

new.d1=ddply(d1, c("Gender", "-Age"))[,-1]
pos=match('M',new.d1$Gender) # pos wil show index of first entry of M
new.d1[c(1:2,pos:(pos+1)),]

答案 3 :(得分:0)

如果您只是想进行排序,那就更容易了:

d1 <- transform(d1[order(d1$Age, decreasing=TRUE), ], Gender=as.factor(Gender))

然后你可以打电话:

require(plyr)
d1 <- ddply(d1, .(Gender), head, n=2)

将每个性别小组的前两个分组。

答案 4 :(得分:0)

如果您需要,例如前两位女性和前三位男性,我有一个建议:

library(plyr)
m<-d1[order(d1$Age, decreasing = TRUE) , ] 
h<-mapply(function(x,y) head(x,y), split(m$Age,m$Gender),y=c(2,3)) 
ldply (h, data.frame)

您只需要更改最终数据帧的名称。

答案 5 :(得分:0)

d1 = d1[order(d1$Gender, -d1$Age),]  
d1 = d1[ave(d1$Age, d1$Gender, FUN = seq_along) <= 2, ]

有一个类似的问题,发现这种方法在具有150万条记录的data.frame上使用时非常快