8

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

我在这里寻找 order、sort 和其他解决方案,但找不到适合此问题的解决方案。我感谢您的帮助。

4

6 回答 6

13

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

require(plyr)
ddply(d1, "Gender", function(x) head(x[order(x$Age, decreasing = TRUE) , ], 2))
于 2011-05-20T18:05:30.063 回答
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]
于 2011-05-20T18:34:56.787 回答
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)),]
于 2011-05-20T18:08:55.587 回答
0

如果您只想进行排序,这甚至比这更容易:

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

然后您可以致电:

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

对每个 Gender 子组的前两个进行子集化。

于 2011-09-25T16:56:20.577 回答
0

如果您需要前 2 位女性和前 3 位男性,我有一个建议:

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)

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

于 2017-01-05T19:28:06.577 回答
0
d1 = d1[order(d1$Gender, -d1$Age),]  
d1 = d1[ave(d1$Age, d1$Gender, FUN = seq_along) <= 2, ]

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

于 2019-03-30T10:54:25.383 回答