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

问题描述 投票:8回答:6

我想为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  

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

r group-by data.table plyr
6个回答
13
投票

使用来自ddply()plyr的一种解决方案

require(plyr)
ddply(d1, "Gender", function(x) head(x[order(x$Age, decreasing = TRUE) , ], 2))

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]

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)),]

0
投票

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

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

然后你可以打电话:

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

将每个性别子组的前两个子集化。


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)

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


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

有一个类似的问题,并发现这个方法真的很快用于具有150万条记录的data.frame

© www.soinside.com 2019 - 2024. All rights reserved.