각 그룹에서 최대값이 있는 행 선택
각 주제에 대해 여러 개의 관측치가 있는 데이터 집합입니다.각 제목에 대해 최대값이 'pt'인 행을 선택합니다.예를 들어, 다음과 같은 데이터 집합이 있습니다.
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)
# Subject pt Event
# 1 1 2 1
# 2 1 3 1
# 3 1 5 2 # max 'pt' for Subject 1
# 4 2 2 1
# 5 2 5 2
# 6 2 8 1
# 7 2 17 2 # max 'pt' for Subject 2
# 8 3 3 2
# 9 3 5 2 # max 'pt' for Subject 3
주제 1, 2, 3의 pt 값이 각각 5, 17, 5로 가장 큽니다.
먼저 각 주제에 대한 가장 큰 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
▁value▁of▁▁just▁first▁max▁you▁if▁like오'd시하십첫같이.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
이 경우 데이터 그룹 내에 여러 최대값이 없으므로 차이가 없습니다.
은 가장직관방다같법습다니음과은인적▁is를 사용하는 것입니다.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
다음을 사용하여 보다 짧은 솔루션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
1.1.0
slice_max(group, pt, by = 'Subject')
{) {dplyr} v1.0.0(2020년 5월)이 .slice_*
를 하는 구문top_n()
.
https://dplyr.tidyverse.org/reference/slice.html 도 참조하십시오.
library(tidyverse)
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) %>%
slice_max(pt)
#> # A tibble: 3 x 3
#> # Groups: Subject [3]
#> Subject pt Event
#> <dbl> <dbl> <dbl>
#> 1 1 5 2
#> 2 2 17 2
#> 3 3 5 2
reprex 패키지(v0.3.0.9001)에 의해 2020-08-18에 생성되었습니다.
A 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
do.call(rbind, lapply(split(group,as.factor(group$Subject)), function(x) {return(x[which.max(x$pt),])}))
사용하기R
이벤트 열에 대해 무엇을 하고 싶은지 확신할 수 없었지만, 만약 당신이 그것도 유지하고 싶다면, 어때요?
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
"Value"합니다. "ID"는 "Value"입니다.그런 다음 어떤 값이 최대값인지 결정한 다음 원래 data.frame의 부분 집합을 만드는 데 사용할 수 있는 논리 벡터로 변환합니다.
기본 R 솔루션 하나 더:
merge(aggregate(pt ~ Subject, max, data = group), group)
Subject pt Event
1 1 5 2
2 2 17 2
3 3 5 2
다른 기본 솔루션
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
사용할 수 있는 베이스ave
갖기 위해max
를 해보도록 하겠습니다.pt
그고논벡얻부어설집다정니합합을분리터의 을 구합니다.data.frame
.
group[group$pt == ave(group$pt, group$Subject, FUN=max),]
# Subject pt Event
#3 1 5 2
#7 2 17 2
#9 3 5 2
로 는또추사용을 것.with
.
group[with(group, pt == ave(pt, Subject, FUN=max)),]
또는 함수에서 이미 비교할 수 있습니다.
group[as.logical(ave(group$pt, group$Subject, FUN=function(x) x==max(x))),]
#group[ave(group$pt, group$Subject, FUN=function(x) x==max(x))==1,] #Variant
또 의 여또있다니습이 있습니다.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]
하나의 른다.data.table
솔루션:
library(data.table)
setDT(group)[, head(.SD[order(-pt)], 1), by = .(Subject)]
by
는 의버니다입의 입니다.tapply
데이터 프레임의 경우:
res <- by(group, group$Subject, FUN=function(df) df[which.max(df$pt),])
▁object의 객체를 합니다.by
데이터 프레임으로 변환합니다.
do.call(rbind, b)
Subject pt Event
1 1 5 2
2 2 17 2
3 3 5 2
하나의 른다.data.table
옵션:
library(data.table)
setDT(group)
group[group[order(-pt), .I[1L], Subject]$V1]
또는 다른 것(가독성은 낮지만 약간 빠름):
group[group[, rn := .I][order(Subject, -pt), {
rn[c(1L, 1L + which(diff(Subject)>0L))]
}]]
타이밍 코드:
library(data.table)
nr <- 1e7L
ng <- nr/4L
set.seed(0L)
DT <- data.table(Subject=sample(ng, nr, TRUE), pt=1:nr)#rnorm(nr))
DT2 <- copy(DT)
microbenchmark::microbenchmark(times=3L,
mtd0 = {a0 <- DT[DT[, .I[which.max(pt)], by=Subject]$V1]},
mtd1 = {a1 <- DT[DT[order(-pt), .I[1L], Subject]$V1]},
mtd2 = {a2 <- DT2[DT2[, rn := .I][
order(Subject, -pt), rn[c(TRUE, diff(Subject)>0L)]
]]},
mtd3 = {a3 <- unique(DT[order(Subject, -pt)], by="Subject")}
)
fsetequal(a0[order(Subject)], a1[order(Subject)])
#[1] TRUE
fsetequal(a0[order(Subject)], a2[, rn := NULL][order(Subject)])
#[1] TRUE
fsetequal(a0[order(Subject)], a3[order(Subject)])
#[1] TRUE
시간:
Unit: seconds
expr min lq mean median uq max neval
mtd0 3.256322 3.335412 3.371439 3.414502 3.428998 3.443493 3
mtd1 1.733162 1.748538 1.786033 1.763915 1.812468 1.861022 3
mtd2 1.136307 1.159606 1.207009 1.182905 1.242359 1.301814 3
mtd3 1.123064 1.166161 1.228058 1.209257 1.280554 1.351851 3
dplyr 1.0.2를 사용하면 이제 두 가지 방법이 있습니다. 하나는 긴 손이고 다른 하나는 동사를 사용하는 것입니다.
# create data
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)
긴 손으로 동사는 max()이지만, 닫힌 질문과 같이 NA가 있는 예에 유용한 na.rm = TRUE를 기록합니다.행이 분리되고 NA가 포함된 데이터 프레임에서 행을 병합합니다.
group %>%
group_by(Subject) %>%
summarise(pt = max(pt, na.rm = TRUE),
Event = max(Event, na.rm = TRUE))
열이 몇 개만 있는 경우에는 괜찮지만 테이블에 가로()로 열이 여러 개 있는 경우에는 유용합니다.이 동사의 예는 종종 요약(cross(start_with...)과 함께 있습니다.그러나 이 예제에서는 열이 동일한 문자로 시작하지 않습니다.변경할 수 있거나 나열된 위치:
group %>%
group_by(Subject) %>%
summarise(across(1:ncol(group)-1, max, na.rm = TRUE, .names = "{.col}"))
동사 가로쓰기() 1은 첫 번째 실제 열 뒤의 첫 번째 열을 참조하므로 ncol(그룹)을 사용하면 열이 너무 많기 때문에 작동하지 않습니다(3이 아닌 위치 4가 됩니다).
저는 때때로 해결책에 의존합니다.order
함수는 모든 유형의 열(즉, 열)에 대해 작동합니다.숫자 뿐만 아니라).기본적으로 테이블을 최대 또는 최소로 정렬한 다음 각 그룹의 첫 번째 또는 마지막을 선택합니다.
저는 또한 이것이 꽤 쉽게 읽을 수 있다고 생각합니다.data.table
초보자
library(data.table)
setDT(group)[order(pt)][, last(.SD), by = Subject]
참고: 대체last
와 함께first
최소값에 해당하는 값을 달성합니다.
와 함께dplyr 1.1.0
사용할 수 있습니다.slice_max
와 함께by
인라인 그룹화 슬라이싱을 수행하는 방법
library(dplyr)
group %>%
slice_max(pt, n = 1, by = Subject)
# Subject pt Event
#1 1 5 2
#2 2 17 2
#3 3 5 2
제목에 대해 가장 큰 pt 값을 원하는 경우 다음을 사용할 수 있습니다.
pt_max = as.data.frame(aggregate(pt~Subject, group, max))
언급URL : https://stackoverflow.com/questions/24558328/select-the-row-with-the-maximum-value-in-each-group
'programing' 카테고리의 다른 글
매개 변수를 사용하여 쿼리 또는 명령을 실행할 때 Dapper가 Oracle Exception을 실행하는 이유는 무엇입니까? (0) | 2023.06.10 |
---|---|
장시간(예: 몇 분) 동안 타이머 설정 (0) | 2023.06.05 |
Android에서 상태 표시줄 색을 변경하는 방법은 무엇입니까? (0) | 2023.06.05 |
인스턴스 상태 저장을 사용하여 활동 상태를 저장하려면 어떻게 해야 합니까? (0) | 2023.06.05 |
Firebase web user.reauthenticate에 필요한 "credential" 개체를 만드는 방법자격 증명() 메서드를 사용하시겠습니까? (0) | 2023.06.05 |