dplyr로 여러 열을 요약하시겠습니까?
저는 dplyr-syntax 때문에 좀 힘들어요.다른 변수와 그룹화 변수가 하나 있는 데이터 프레임이 있습니다.이제 R에서 dplyr을 사용하여 각 그룹 내의 각 열에 대한 평균을 계산하려고 합니다.
df <- data.frame(
a = sample(1:5, n, replace = TRUE),
b = sample(1:5, n, replace = TRUE),
c = sample(1:5, n, replace = TRUE),
d = sample(1:5, n, replace = TRUE),
grp = sample(1:3, n, replace = TRUE)
)
df %>% group_by(grp) %>% summarise(mean(a))
이것은 "grp"로 표시된 각 그룹에 대한 열 "a"의 평균을 제공합니다.
제 질문은 각 그룹의 각 열에 대한 평균을 한 번에 얻을 수 있느냐는 것입니다.아니면 반복해야 하나요?df %>% group_by(grp) %>% summarise(mean(a))
각 열에 대해?
제가 갖고 싶은 것은 다음과 같습니다.
df %>% group_by(grp) %>% summarise(mean(a:d)) # "mean(a:d)" does not work
인dplyr
(>=1.00)을 사용할 수 있습니다.across(everything()
에summarise
함수를 모든 변수에 적용하는 방법
library(dplyr)
df %>% group_by(grp) %>% summarise(across(everything(), list(mean)))
#> # A tibble: 3 x 5
#> grp a b c d
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 3.08 2.98 2.98 2.91
#> 2 2 3.03 3.04 2.97 2.87
#> 3 3 2.85 2.95 2.95 3.06
대신에,purrrlyr
패키지는 동일한 기능을 제공합니다.
library(purrrlyr)
df %>% slice_rows("grp") %>% dmap(mean)
#> # A tibble: 3 x 5
#> grp a b c d
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 3.08 2.98 2.98 2.91
#> 2 2 3.03 3.04 2.97 2.87
#> 3 3 2.85 2.95 2.95 3.06
또한 잊지 마세요.data.table
(사용)keyby
그룹 정렬):
library(data.table)
setDT(df)[, lapply(.SD, mean), keyby = grp]
#> grp a b c d
#> 1: 1 3.079412 2.979412 2.979412 2.914706
#> 2: 2 3.029126 3.038835 2.967638 2.873786
#> 3: 3 2.854701 2.948718 2.951567 3.062678
성능을 비교해 보겠습니다.
library(dplyr)
library(purrrlyr)
library(data.table)
library(bench)
set.seed(123)
n <- 10000
df <- data.frame(
a = sample(1:5, n, replace = TRUE),
b = sample(1:5, n, replace = TRUE),
c = sample(1:5, n, replace = TRUE),
d = sample(1:5, n, replace = TRUE),
grp = sample(1:3, n, replace = TRUE)
)
dt <- setDT(df)
mark(
dplyr = df %>% group_by(grp) %>% summarise(across(everything(), list(mean))),
purrrlyr = df %>% slice_rows("grp") %>% dmap(mean),
data.table = dt[, lapply(.SD, mean), keyby = grp],
check = FALSE
)
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 dplyr 2.81ms 2.85ms 328. NA 17.3
#> 2 purrrlyr 7.96ms 8.04ms 123. NA 24.5
#> 3 data.table 596.33µs 707.91µs 1409. NA 10.3
다음을 사용하여 요약할 수 있습니다.summarize_at
,summarize_all
그리고.summarize_if
에dplyr 0.7.4
다음을 사용하여 여러 열 및 함수를 설정할 수 있습니다.vars
그리고.funs
아래 코드와 같은 인수입니다.재미의 왼쪽 공식은 요약된 변수의 접미사에 할당됩니다.에서dplyr 0.7.4
,summarise_each
(및mutate_each
)는 이미 더 이상 사용되지 않으므로 이러한 기능을 사용할 수 없습니다.
options(scipen = 100, dplyr.width = Inf, dplyr.print_max = Inf)
library(dplyr)
packageVersion("dplyr")
# [1] ‘0.7.4’
set.seed(123)
df <- data_frame(
a = sample(1:5, 10, replace=T),
b = sample(1:5, 10, replace=T),
c = sample(1:5, 10, replace=T),
d = sample(1:5, 10, replace=T),
grp = as.character(sample(1:3, 10, replace=T)) # For convenience, specify character type
)
df %>% group_by(grp) %>%
summarise_each(.vars = letters[1:4],
.funs = c(mean="mean"))
# `summarise_each()` is deprecated.
# Use `summarise_all()`, `summarise_at()` or `summarise_if()` instead.
# To map `funs` over a selection of variables, use `summarise_at()`
# Error: Strings must match column names. Unknown columns: mean
당신은 다음 코드로 변경해야 합니다.다음 코드는 모두 결과가 동일합니다.
# summarise_at
df %>% group_by(grp) %>%
summarise_at(.vars = letters[1:4],
.funs = c(mean="mean"))
df %>% group_by(grp) %>%
summarise_at(.vars = names(.)[1:4],
.funs = c(mean="mean"))
df %>% group_by(grp) %>%
summarise_at(.vars = vars(a,b,c,d),
.funs = c(mean="mean"))
# summarise_all
df %>% group_by(grp) %>%
summarise_all(.funs = c(mean="mean"))
# summarise_if
df %>% group_by(grp) %>%
summarise_if(.predicate = function(x) is.numeric(x),
.funs = funs(mean="mean"))
# A tibble: 3 x 5
# grp a_mean b_mean c_mean d_mean
# <chr> <dbl> <dbl> <dbl> <dbl>
# 1 1 2.80 3.00 3.6 3.00
# 2 2 4.25 2.75 4.0 3.75
# 3 3 3.00 5.00 1.0 2.00
여러 기능을 사용할 수도 있습니다.
df %>% group_by(grp) %>%
summarise_at(.vars = letters[1:2],
.funs = c(Mean="mean", Sd="sd"))
# A tibble: 3 x 5
# grp a_Mean b_Mean a_Sd b_Sd
# <chr> <dbl> <dbl> <dbl> <dbl>
# 1 1 2.80 3.00 1.4832397 1.870829
# 2 2 4.25 2.75 0.9574271 1.258306
# 3 3 3.00 5.00 NA NA
더 많은 인수를 에 전달할 수 있습니다.summarise
:
df %>% group_by(grp) %>% summarise(mean(a), mean(b), mean(c), mean(d))
출처: 로컬 데이터 프레임 [3 x 5]
grp mean(a) mean(b) mean(c) mean(d)
1 1 2.500000 3.500000 2.000000 3.0
2 2 3.800000 3.200000 3.200000 2.8
3 3 3.666667 3.333333 2.333333 3.0
완전성을 위해: dplyr v0.2 사용ddply
와 함께colwise
다음 작업도 수행합니다.
> ddply(df, .(grp), colwise(mean))
grp a b c d
1 1 4.333333 4.00 1.000000 2.000000
2 2 2.000000 2.75 2.750000 2.750000
3 3 3.000000 4.00 4.333333 3.666667
하지만 적어도 이 경우에는 더 느립니다.
> microbenchmark(ddply(df, .(grp), colwise(mean)),
df %>% group_by(grp) %>% summarise_each(funs(mean)))
Unit: milliseconds
expr min lq mean
ddply(df, .(grp), colwise(mean)) 3.278002 3.331744 3.533835
df %>% group_by(grp) %>% summarise_each(funs(mean)) 1.001789 1.031528 1.109337
median uq max neval
3.353633 3.378089 7.592209 100
1.121954 1.133428 2.292216 100
모든 예시들이 훌륭하지만, 저는 "정리된" 형식으로 작업하는 것이 어떻게 일을 단순화하는지 보여주기 위해 하나를 더 추가할 것이라고 생각합니다.현재 데이터 프레임은 "넓은" 형식입니다. 즉, 변수 "a" ~ "d"가 열로 표시됩니다."tidy"(또는 긴) 형식으로 이동하려면 다음을 사용할 수 있습니다.gather()
에서tidyr
열 "a"에서 "d" 사이의 변수를 행으로 이동시키는 패키지.그런 다음 사용합니다.group_by()
그리고.summarize()
각 그룹의 평균을 구하는 함수입니다.데이터를 광범위한 형식으로 표시하려면 추가 호출을 선택합니다.spread()
기능.
library(tidyverse)
# Create reproducible df
set.seed(101)
df <- tibble(a = sample(1:5, 10, replace=T),
b = sample(1:5, 10, replace=T),
c = sample(1:5, 10, replace=T),
d = sample(1:5, 10, replace=T),
grp = sample(1:3, 10, replace=T))
# Convert to tidy format using gather
df %>%
gather(key = variable, value = value, a:d) %>%
group_by(grp, variable) %>%
summarize(mean = mean(value)) %>%
spread(variable, mean)
#> Source: local data frame [3 x 5]
#> Groups: grp [3]
#>
#> grp a b c d
#> * <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 3.000000 3.5 3.250000 3.250000
#> 2 2 1.666667 4.0 4.666667 2.666667
#> 3 3 3.333333 3.0 2.333333 2.333333
언급URL : https://stackoverflow.com/questions/21644848/summarizing-multiple-columns-with-dplyr
'programing' 카테고리의 다른 글
PDF에서 페이지를 JPEG로 추출 (0) | 2023.06.06 |
---|---|
브라우저를 통해 mongodb에 액세스할 수 없음 - 네이티브 드라이버 포트에서 HTTP를 통해 MongoDB에 액세스하려고 하는 것 같습니다. (0) | 2023.06.06 |
오류: Firebase ID 토큰이 만료되었습니다. (0) | 2023.06.06 |
VBA에서 사용된 마지막 행을 결정하는 방법(빈칸 포함) (0) | 2023.06.06 |
ld option -lrt가 가리키는 라이브러리는 무엇입니까(바이오닉 libc)? (0) | 2023.06.06 |