dplyr 필터 : 최소 변수가있는 행을 가져 오지만 최소값이 여러 개인 경우 첫 번째 행만 가져옵니다.
dplyr
각 그룹 내에서 변수의 최소값을 가진 해당 행만 반환되는 방식 으로을 사용하여 그룹화 된 필터를 만들고 싶습니다 x
.
내 문제는 예상대로 여러 최소값의 경우 최소값을 가진 모든 행이 반환됩니다. 하지만 제 경우에는 최소값이 여러 개인 경우 첫 번째 행만 원합니다 .
예를 들면 다음과 같습니다.
df <- data.frame(
A=c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
x=c(1, 1, 2, 2, 3, 4, 5, 5, 5),
y=rnorm(9)
)
library(dplyr)
df.g <- group_by(df, A)
filter(df.g, x == min(x))
예상대로 모든 최소값이 반환됩니다.
Source: local data frame [6 x 3]
Groups: A
A x y
1 A 1 -1.04584335
2 A 1 0.97949399
3 B 2 0.79600971
4 C 5 -0.08655151
5 C 5 0.16649962
6 C 5 -0.05948012
ddply를 사용하면 다음과 같이 작업에 접근했을 것입니다.
library(plyr)
ddply(df, .(A), function(z) {
z[z$x == min(z$x), ][1, ]
})
... 작동합니다 :
A x y
1 A 1 -1.04584335
2 B 2 0.79600971
3 C 5 -0.08655151
Q : dplyr에서 이에 접근하는 방법이 있습니까? (속도상의 이유로)
최신 정보
dplyr> = 0.3을 사용하면 이 작업에 대해 제가 가장 좋아하는 접근 방식 인와 함께 slice
함수를 사용할 수 있습니다 which.min
.
df %>% group_by(A) %>% slice(which.min(x))
#Source: local data frame [3 x 3]
#Groups: A
#
# A x y
#1 A 1 0.2979772
#2 B 2 -1.1265265
#3 C 5 -1.1952004
원래 답변
샘플 데이터의 경우 두 개를 차례로 사용할 수도 있습니다 filter
.
group_by(df, A) %>%
filter(x == min(x)) %>%
filter(1:n() == 1)
완전성을 위해 : 다음 dplyr
은 @hadley 및 @Arun의 의견에서 파생 된 최종 솔루션입니다.
library(dplyr)
df.g <- group_by(df, A)
filter(df.g, rank(x, ties.method="first")==1)
그 가치에 data.table
대해 관심이있는 사람들을 위한 해결책이 있습니다.
# approach with setting keys
dt <- as.data.table(df)
setkey(dt, A,x)
dt[J(unique(A)), mult="first"]
# without using keys
dt <- as.data.table(df)
dt[dt[, .I[which.min(x)], by=A]$V1]
이것은 사용하여 수행 할 수 있습니다 row_number
와 함께 group_by
. row_number
값뿐만 아니라 벡터 내 상대적 순서에 따라 순위를 할당하여 동점을 처리합니다. 최소값이 x
다음 과 같은 각 그룹의 첫 번째 행을 가져 오려면
df.g <- group_by(df, A)
filter(df.g, row_number(x) == 1)
자세한 내용은 창 기능에 대한 dplyr 비 네트를 참조하십시오 .
I like sqldf for its simplicity..
sqldf("select A,min(X),y from 'df.g' group by A")
Output:
A min(X) y
1 A 1 -1.4836989
2 B 2 0.3755771
3 C 5 0.9284441
Another way to do it:
set.seed(1)
x <- data.frame(a = rep(1:2, each = 10), b = rnorm(20))
x <- dplyr::arrange(x, a, b)
dplyr::filter(x, !duplicated(a))
Result:
a b
1 1 -0.8356286
2 2 -2.2146999
Could also be easily adapted for getting the row in each group with maximum value.
Came here looking for a way to do this with more than one. This will give the bottom ten, breaking ties by last, I believe
df.g %>%
top_n(-10,row_number(x))
'program story' 카테고리의 다른 글
//로 CSS 한 줄을 주석 처리하는 것은 나쁜 습관입니까? (0) | 2020.11.30 |
---|---|
연결시 알 수없는 SSL 프로토콜 오류 (0) | 2020.11.30 |
moment.js를 사용하여 이번 달의 일 수 가져 오기 (0) | 2020.11.30 |
다중 클라이언트 응용 프로그램에 대해 단일 또는 다중 데이터베이스 설정을 사용해야합니까? (0) | 2020.11.30 |
자동 증가로 열의 시작 값 설정 (0) | 2020.11.30 |