当使用
dplyr
创建按变量级别组织的汇总统计表时,我无法在不重复列名的情况下找出计算四分位数的语法。也就是说,使用调用(例如 vars()
和 list()
)可以与其他函数(例如 mean()
和 median()
)一起使用,但不能与 quantile()
一起使用
搜索产生了过时的解决方案,这些解决方案不再有效,因为它们使用已弃用的调用,例如
do()
和/或 funs()
。
data(iris)
library(tidyverse)
#This works: Notice I have not attempted to calculate quartiles yet
summary_stat <- iris %>%
group_by(Species) %>%
summarise_at(vars(Sepal.Length),
list(min=min, median=median, max=max,
mean=mean, sd=sd)
)
A tibble: 3 x 6
Species min median max mean sd
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 5 5.8 5.01 0.352
2 versicolor 4.9 5.9 7 5.94 0.516
3 virginica 4.9 6.5 7.9 6.59 0.636
##########################################################################
#Does NOT work:
five_number_summary <- iris %>%
group_by(Species) %>%
summarise_at(vars(Sepal.Length),
list(min=min, Q1=quantile(.,probs = 0.25),
median=median, Q3=quantile(., probs = 0.75),
max=max))
Error: Must use a vector in `[`, not an object of class matrix.
Call `rlang::last_error()` to see a backtrace
###########################################################################
#This works: Remove the vars() argument, remove the list() argument,
#replace summarise_at() with summarise()
#but the code requires repeating the column name (Sepal.Length)
five_number_summary <- iris %>%
group_by(Species) %>%
summarise(min=min(Sepal.Length),
Q1=quantile(Sepal.Length,probs = 0.25),
median=median(Sepal.Length),
Q3=quantile(Sepal.Length, probs = 0.75),
max=max(Sepal.Length))
# A tibble: 3 x 6
Species min Q1 median Q3 max
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 4.8 5 5.2 5.8
2 versicolor 4.9 5.6 5.9 6.3 7
3 virginica 4.9 6.22 6.5 6.9 7.9
最后一段代码产生的正是我正在寻找的内容,但我想知道为什么没有更短的语法不会迫使我重复该变量。
您在失败的
~
调用中缺少 quantile
函数前面的 summarise_at
。尝试以下操作:
five_number_summary <- iris %>%
group_by(Species) %>%
summarise_at(vars(Sepal.Length),
list(min=min, Q1=~quantile(., probs = 0.25),
median=median, Q3=~quantile(., probs = 0.75),
max=max))
five_number_summary
# A tibble: 3 x 6
Species min Q1 median Q3 max
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 setosa 4.3 4.8 5 5.2 5.8
2 versicolor 4.9 5.6 5.9 6.3 7
3 virginica 4.9 6.22 6.5 6.9 7.9
您可以在
summarise
内创建数据框/小标题,然后将其拼接成单独的列。
library(tidyverse)
iris %>%
group_by(Species) %>%
summarise(as_tibble_row(quantile(Sepal.Length)))
#> # A tibble: 3 × 6
#> Species `0%` `25%` `50%` `75%` `100%`
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 setosa 4.3 4.8 5 5.2 5.8
#> 2 versicolor 4.9 5.6 5.9 6.3 7
#> 3 virginica 4.9 6.22 6.5 6.9 7.9
# with .name_repair
iris %>%
group_by(Species) %>%
summarise(as_tibble_row(quantile(Sepal.Length), .name_repair = \(x) paste0('q', parse_number(x))))
#> # A tibble: 3 × 6
#> Species q0 q25 q50 q75 q100
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 setosa 4.3 4.8 5 5.2 5.8
#> 2 versicolor 4.9 5.6 5.9 6.3 7
#> 3 virginica 4.9 6.22 6.5 6.9 7.9
创建于 2023-12-30,使用 reprex v2.0.2
您可以创建一个列表列,然后使用
unnest_wider
,这需要tidyr 1.0.0
library(tidyverse)
iris %>%
group_by(Species) %>%
summarise(q = list(quantile(Sepal.Length))) %>%
unnest_wider(q)
# # A tibble: 3 x 6
# Species `0%` `25%` `50%` `75%` `100%`
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 setosa 4.3 4.8 5 5.2 5.8
# 2 versicolor 4.9 5.6 5.9 6.3 7
# 3 virginica 4.9 6.22 6.5 6.9 7.9
有一个
names_repair
参数,但显然它会更改所有列的名称,而不仅仅是未嵌套的列的名称 (??)
iris %>%
group_by(Species) %>%
summarise(q = list(quantile(Sepal.Length))) %>%
unnest_wider(q, names_repair = ~paste0('Q_', sub('%', '', .)))
# # A tibble: 3 x 6
# Q_Species Q_0 Q_25 Q_50 Q_75 Q_100
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 setosa 4.3 4.8 5 5.2 5.8
# 2 versicolor 4.9 5.6 5.9 6.3 7
# 3 virginica 4.9 6.22 6.5 6.9 7.9
另一个选择是
group_modify
iris %>%
group_by(Species) %>%
group_modify(~as.data.frame(t(quantile(.$Sepal.Length))))
# # A tibble: 3 x 6
# # Groups: Species [3]
# Species `0%` `25%` `50%` `75%` `100%`
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 setosa 4.3 4.8 5 5.2 5.8
# 2 versicolor 4.9 5.6 5.9 6.3 7
# 3 virginica 4.9 6.22 6.5 6.9 7.9
或者你可以使用 data.table
library(data.table)
irisdt <- as.data.table(iris)
irisdt[, as.list(quantile(Sepal.Length)), Species]
# Species 0% 25% 50% 75% 100%
# 1: setosa 4.3 4.800 5.0 5.2 5.8
# 2: versicolor 4.9 5.600 5.9 6.3 7.0
# 3: virginica 4.9 6.225 6.5 6.9 7.9
关于@arienrhod 最新版本的注释
library(dplyr,quietly = TRUE,verbose = FALSE, warn.conflicts = FALSE)
five_number_summary <- iris %>%
group_by(Species) %>%
summarise(across(Sepal.Length, list(min=min, Q1=~quantile(., probs = 0.25),
median=median, Q3=~quantile(., probs = 0.75),
max=max), .names = "{.fn}"))
five_number_summary
#> # A tibble: 3 x 6
#> Species min Q1 median Q3 max
#> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 setosa 4.3 4.8 5 5.2 5.8
#> 2 versicolor 4.9 5.6 5.9 6.3 7
#> 3 virginica 4.9 6.22 6.5 6.9 7.9
由 reprex 包于 2022 年 2 月 21 日创建(v2.0.1)