Как выбрать строку с максимальным значением в каждой группе
В настоящее время я имею проблему следующим образом. В наборе данных, где есть несколько наблюдений для каждого объекта, и я хочу сделать подмножество этого набора данных, в котором будут выбраны только максимальные данные для записи. Например, для набора данных, как показано ниже:
ID <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
group <- data.frame(Subject=ID, pt=Value, Event=Event)
Субъекты 1, 2 и 3 имеют наибольшее значение pt 5, 17 и 5 соответственно. Как я мог сначала найти наибольшее значение pt для каждого объекта, а затем поставить это наблюдение в другой фрейм данных? Это означает, что это подмножество будет иметь самые большие значения pt для каждого объекта.
Ответы
Ответ 1
Здесь a data.table
решение:
require(data.table) ## 1.9.2
group <- as.data.table(group)
Если вы хотите сохранить все записи, соответствующие максимальным значениям pt
в каждой группе:
group[group[, .I[pt == max(pt)], by=Subject]$V1]
# Subject pt Event
# 1: 1 5 2
# 2: 2 17 2
# 3: 3 5 2
Если вы хотите только первое максимальное значение pt
:
group[group[, .I[which.max(pt)], by=Subject]$V1]
# Subject pt Event
# 1: 1 5 2
# 2: 2 17 2
# 3: 3 5 2
В этом случае это не имеет значения, так как в вашей группе не существует нескольких максимальных значений.
Ответ 2
Самый интуитивный метод - использовать функции group_by и top_n в dplyr
group %>% group_by(Subject) %>% top_n(1, pt)
Результат:
Source: local data frame [3 x 3]
Groups: Subject [3]
Subject pt Event
(dbl) (dbl) (dbl)
1 1 5 2
2 2 17 2
3 3 5 2
Ответ 3
Более короткое решение с использованием data.table
:
setDT(group)[, .SD[which.max(pt)], by=Subject]
# Subject pt Event
# 1: 1 5 2
# 2: 2 17 2
# 3: 3 5 2
Ответ 4
Решение dplyr
:
library(dplyr)
ID <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
group <- data.frame(Subject=ID, pt=Value, Event=Event)
group %>%
group_by(Subject) %>%
summarize(max.pt = max(pt))
Это дает следующий фрейм данных:
Subject max.pt
1 1 5
2 2 17
3 3 5
Ответ 5
Я не был уверен, что вы хотите сделать в столбце "Событие", но если вы хотите сохранить это, как насчет
isIDmax <- with(dd, ave(Value, ID, FUN=function(x) seq_along(x)==which.max(x)))==1
group[isIDmax, ]
# ID Value Event
# 3 1 5 2
# 7 2 17 2
# 9 3 5 2
Здесь мы используем ave
для просмотра столбца "Значение" для каждого "идентификатора". Затем мы определяем, какое значение является максимальным, а затем превращаем его в логический вектор, который мы можем использовать для подмножества исходного кадра данных.
Ответ 6
Другой вариант: slice
library(dplyr)
group %>%
group_by(Subject) %>%
slice(which.max(pt))
# Subject pt Event
# <dbl> <dbl> <dbl>
#1 1 5 2
#2 2 17 2
#3 3 5 2
Ответ 7
do.call(rbind, lapply(split(group,as.factor(group$Subject)), function(x) {return(x[which.max(x$pt),])}))
Использование Base R
Ответ 8
Здесь другое решение data.table
, так как which.max
не работает с символами
library(data.table)
group <- data.table(Subject=ID, pt=Value, Event=Event)
group[, .SD[order(pt, decreasing = TRUE) == 1], by = Subject]
Ответ 9
Еще одно базовое решение
group_sorted <- group[order(group$Subject, -group$pt),]
group_sorted[!duplicated(group_sorted$Subject),]
# Subject pt Event
# 1 5 2
# 2 17 2
# 3 5 2
Упорядочить фрейм данных по pt
(по убыванию) и удалить строки, дублированные в Subject
Ответ 10
Если вы хотите получить наибольшее значение pt для субъекта, вы можете просто использовать:
pt_max = as.data.frame(aggregate(pt~Subject, group, max))