Как получить максимальное значение по группе
У меня есть data.frame
с двумя столбцами: year
и score
. Годы идут с 2000-2012 года и каждый год могут быть перечислены несколько раз. В столбце оценки я перечисляю все баллы за каждый год, причем каждая строка имеет разный балл.
То, что я хотел бы сделать, – это фильтр data.frame
так что data.frame
только строки с максимальным количеством баллов за каждый год.
Итак, как крошечный пример, если у меня есть
- Подмножество data.table с использованием переменных с тем же именем, что и в столбце
- Как сгладить список в список без принуждения?
- Скользящее среднее из предыдущих трех значений в R
- Удаление столбцов из фрейма данных, где ВСЕ значения NA
- Что делать и делать, когда делаете сюжет с помощью ggplot?
year score 2000 18 2001 22 2000 21
Я бы хотел вернуться только
year score 2001 22 2000 21
- Преобразование эпохи UNIX в объект Date
- Назначить несколько новых переменных на LHS в одной строке
- Как искать материалы «R»?
- Создание динамического количества элементов ввода с помощью R / Shiny
- Оператор "[<-" в RStudio и R
- Как инициализировать пустой фрейм данных (количество столбцов одновременно) в R
- Удаление отображения имен строк из фрейма данных
- Упорядоченный график столбцов в ggplot
Если вы знаете 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
require(data.table) dt <- data.table(df, key="year") dt[, list(max.score=max(score)), by=year]
используя 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
использование базовых пакетов
> 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
РЕДАКТИРОВАТЬ
Если у вас есть дополнительные столбцы, которые вам нужно сохранить, вы можете merge
пользователя с помощью aggregate
чтобы получить эти столбцы
> 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
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_2<-data.frame(year=sort(unique(df$year)),score = tapply(df$score,df$year,max));