2011-05-20 46 views
7

我想爲n行分配一個數據框,這些行由一個變量分組並按另一個變量排序。這將通過一個例子清楚:爲每個組設置前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 

我在這裏查找訂單,排序和其他解決方案,但無法找到適合此問題的解決方案。我感謝您的幫助。使用ddply()

+1

您是否只想要每個性別的最大兩個年齡段? – kmm 2011-05-20 17:47:24

回答

13

一個解決方案,從plyr

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

在發佈我的郵件之前,我沒有看到您的答案!好多了。 – 2011-05-20 18:13:05

+0

美麗地工作!我甚至可以修改「n」值。謝謝。 – karlos 2011-05-20 18:24:52

+0

+1仍然有效,如果有關係。 – 2011-05-20 18:33:42

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

感謝您的解決方案,Manoel,但我沒有嘗試它作爲追求解決方案爲我工作。 – karlos 2011-05-20 18:25:41

+0

@ karlos,當然。他的解決方案比我的更好。事實上,昨天他剛剛幫我一個問題,他也使用plyr。毫不奇怪,他用'ddply'比我好。 – 2011-05-20 18:35:22

5

隨着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] 
+6

而不是'order(Age,decrease = TRUE)'可以寫'order(-Age)'。這樣你可以按不同的方向排列幾列。例如'order(-Age,+ Height,-Weight)'。 – 2012-05-08 16:22:11

0

它甚至比這更容易,如果你只想做排序:

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

然後你可以撥打:

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

到子集的每個性別小組的前兩名。

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) 

你只需要改變最終數據框的名稱。