我想为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
我在这里寻找订单,排序和其他解决方案,但找不到合适的解决方案来解决这个问题。我感谢您的帮助。
答案 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上使用时非常快