2013-02-14 109 views
4

我有一個data.frame,有兩列:yearscore。從2000年到2012年,每年可以多次上市。在分數列中,我列出了每一年每個分數不同的所有分數。如何按組獲得最大值

我想要做的就是過濾data.frame,這樣只剩下每年最高分數的行。

所以,如果我有

year score 
2000 18 
2001 22 
2000 21 

我想只是

year score 
2001 22 
2000 21 

回答

7

如果您知道sql這很容易理解

library(sqldf) 
sqldf('select year, max(score) from mydata group by year') 

更新(2016-01):現在你也可以使用dplyr

library(dplyr) 
mydata %>% group_by(year) %>% summarise(max = max(score)) 
7

使用plyr

require(plyr) 
set.seed(45) 
df <- data.frame(year=sample(2000:2012, 25, replace=T), score=sample(25)) 
ddply(df, .(year), summarise, max.score=max(score)) 

使用data.table

返回一個很小的例子

使用aggregate

o <- aggregate(df$score, list(df$year) , max) 
names(o) <- c("year", "max.score") 

使用ave

df1 <- df 
df1$max.score <- ave(df1$score, df1$year, FUN=max) 
df1 <- df1[!duplicated(df1$year), ] 

編輯:在多個列的情況下,data.table解決方案是最好的(我認爲:))

set.seed(45) 
df <- data.frame(year=sample(2000:2012, 25, replace=T), score=sample(25), 
       alpha = sample(letters[1:5], 25, replace=T), beta=rnorm(25)) 

# convert to data.table with key=year 
dt <- data.table(df, key="year") 
# get the subset of data that matches this criterion 
dt[, .SD[score %in% max(score)], by=year] 

#  year score alpha  beta 
# 1: 2000 20  b 0.8675148 
# 2: 2001 21  e 1.5543102 
# 3: 2002 22  c 0.6676305 
# 4: 2003 18  a -0.9953758 
# 5: 2004 23  d 2.1829996 
# 6: 2005 25  b -0.9454914 
# 7: 2007 17  e 0.7158021 
# 8: 2008 12  e 0.6501763 
# 9: 2011 24  a 0.7201334 
# 10: 2012 19  d 1.2493954 
+0

如果我想在濾波的結果保持數據的I其他列?例如,假設我有第三列名爲study_hours,這是我爲了獲得特定分數而研究的小時數。我想保留包含最高分數的整個行。 – user1956609 2013-02-14 06:56:18

+0

@ user1956609我修改了我的示例以顯示如何獲取其他列 – 2013-02-14 08:43:01

+0

@ user1956609,在這種情況下,我建議您使用編輯過的'data.table'解決方案。 – Arun 2013-02-14 11:26:50

1
data <- data.frame(year = c(2000, 2001, 2000), score = c(18, 22, 21)) 
new.year <- unique(data$year) 
new.score <- sapply(new.year, function(y) max(data[data$year == y, ]$score)) 
data <- data.frame(year = new.year, score = new.score) 
5

使用基礎包

> df 
    year score 
1 2000 18 
2 2001 22 
3 2000 21 
> aggregate(score ~ year, data=df, max) 
    year score 
1 2000 21 
2 2001 22 

編輯

如果您有需要保留的其他列,那麼你可以在用戶mergeaggregate讓那些列

> df <- data.frame(year = c(2000, 2001, 2000), score = c(18, 22, 21) , hrs = c(10, 11, 12)) 
> df 
    year score hrs 
1 2000 18 10 
2 2001 22 11 
3 2000 21 12 
> merge(aggregate(score ~ year, data=df, max), df, all.x=T) 
    year score hrs 
1 2000 21 12 
2 2001 22 11 
0

一個襯墊,

df_2<-data.frame(year=sort(unique(df$year)),score = tapply(df$score,df$year,max));