[r] 각 그룹에서 최대 값이있는 행을 선택하는 방법

각 주제에 대한 여러 관측치가있는 데이터 세트에서 각 레코드에 대한 최대 데이터 값만있는 하위 집합을 취하려고합니다. 예를 들어 다음 데이터 세트를 사용합니다.

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은 각각 5, 17 및 5의 가장 큰 pt 값을 갖습니다.

먼저 각 주제에 대한 가장 큰 pt 값을 찾은 다음이 관측치를 다른 데이터 프레임에 넣으려면 어떻게해야합니까? 결과 데이터 프레임에는 각 주제에 대해 가장 큰 pt 값만 있어야합니다.



답변

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

이 경우 데이터의 어떤 그룹에도 최대 값이 여러 개 없기 때문에 차이가 없습니다.


답변

가장 직관적 인 방법은 dplyr에서 group_by 및 top_n 함수를 사용하는 것입니다.

    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


답변

다음을 사용하는 더 짧은 솔루션 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


답변

또 다른 옵션은 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


답변

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


답변

이벤트 칼럼에 대해 뭘하고 싶은지 잘 모르겠지만, 그대로 유지하고 싶다면

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에서 각 “ID”에 대한 “값”열을 살펴 봅니다. 그런 다음 어떤 값이 최대 값인지 결정한 다음이를 논리 벡터로 변환하여 원래 데이터 프레임을 부분 집합으로 만듭니다.


답변

do.call(rbind, lapply(split(group,as.factor(group$Subject)), function(x) {return(x[which.max(x$pt),])}))

베이스 사용 R