program tip

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

radiobox 2021. 1. 5. 07:55
반응형

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


현재 다음과 같은 문제가 있습니다. 각 주제에 대한 여러 관측치가 존재하는 데이터 세트에서 레코드의 최대 데이터 만 선택된이 데이터 세트의 하위 집합을 만들고 싶습니다. 예를 들어 아래와 같은 데이터 세트의 경우 :

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

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"에 대한 "값"열을 확인합니다. 그런 다음 어떤 값이 최대 값인지 결정한 다음이를 논리 벡터로 변환하여 원래 data.frame의 부분 집합에 사용할 수 있습니다.


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

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

베이스 사용 R


캐릭터에서 작동하지 않기 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]

또 다른 기본 솔루션

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

Order the data frame by pt (descending) and the remove rows duplicated in Subject


If you want the biggest pt value for a subject, you could simply use:

   pt_max = as.data.frame(aggregate(pt~Subject, group, max))

ReferenceURL : https://stackoverflow.com/questions/24558328/how-to-select-the-row-with-the-maximum-value-in-each-group

반응형