R 对数据帧进行子集设置,每组前n行,并按变量排序

R 对数据帧进行子集设置,每组前n行,并按变量排序,r,group-by,data.table,plyr,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)) 我在这里查找顺序、排序和其他解决方案,但找不到解决此问题的适当方法。我感谢你的帮助 使用plyr require(plyr) ddply(d1, "Gen

我想为n行创建一个子集,这些行按一个变量分组,并按另一个变量降序排序。举个例子就可以清楚地说明这一点:

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

我在这里查找顺序、排序和其他解决方案,但找不到解决此问题的适当方法。我感谢你的帮助

使用
plyr

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

我相信有更好的答案,但有一种方法:

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

使用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]
require(data.table)

dt1如果您只想进行排序,则更容易:

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

d1如果您需要,例如前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)
库(plyr)
m
d1=d1[顺序(d1$性别,-d1$年龄),]

d1=d1[ave(d1$Age,d1$Gender,FUN=seq_-along)你只想要每个性别最大的两个年龄吗?我在发布我的答案之前没有看到你的答案!好多了。效果很好!我甚至可以修改“n”值。谢谢。@brandon,即使你的n大于一组中的实际行数,它也能工作。因此,如果你有6个雌性和5个雄性,并且你将n改为5,你将得到雌性的前5行,所有雄性的前5行。这正是我想要的。谢谢你的解决方案,Manoel,但我没有尝试,因为chase的解决方案对我有效。@karlos,当然。他的解决方案比我的好。事实上,昨天他只是帮我提了一个问题,他也用了plyr。毫不奇怪,他用的“ddply”比我好。而不是
order(Age,discreating=TRUE)
可以写
order(-Age)
。这样,您可以按不同方向的几列进行排序;例如,
顺序(-Age,+Height,-Weight)
require(plyr)
d1 <- ddply(d1, .(Gender), head, n=2)
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)
d1 = d1[order(d1$Gender, -d1$Age),]  
d1 = d1[ave(d1$Age, d1$Gender, FUN = seq_along) <= 2, ]