Подтвердить что ты не робот

Как выбрать строку с максимальным значением в каждой группе

В настоящее время я имею проблему следующим образом. В наборе данных, где есть несколько наблюдений для каждого объекта, и я хочу сделать подмножество этого набора данных, в котором будут выбраны только максимальные данные для записи. Например, для набора данных, как показано ниже:

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 для каждого объекта.

4b9b3361

Ответ 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))