如何按组获得最大值

问题描述:

我有一个data.frame,有两列:yearscore。从2000年到2012年,每年可以多次上市。在分数列中,我列出了每一年每个分数不同的所有分数。如何按组获得最大值

我想要做的就是过滤data.frame,这样只剩下每年最高分数的行。

所以,如果我有

year score 
2000 18 
2001 22 
2000 21 

我想只是

year score 
2001 22 
2000 21 

如果您知道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)) 

使用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

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) 

使用基础包

> 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 

一个衬垫,

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