问题描述
我遇到了dplyr
和across
奇怪的东西,或者至少是我不理解的东西。
如果我们使用跨函数来计算多个列中的mean
和standard error of the mean
,我很想使用以下命令:
mtcars %>% group_by(gear) %>% select(mpg,cyl) %>%
summarize(across(everything(),~mean(.x,na.rm = TRUE),.names = "{col}"),across(everything(),~sd(.x,na.rm=T)/sqrt(sum(!is.na(.x))),.names="se_{col}")) %>% head()
结果
gear mpg cyl se_mpg se_cyl
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3 16.1 7.47 NA NA
2 4 24.5 4.67 NA NA
3 5 21.4 6 NA NA
但是,如果切换单个across
命令的顺序,则会得到以下信息:
mtcars %>% group_by(gear) %>% select(mpg,.names="se_{col}"),.names = "{col}")) %>% head()
# A tibble: 3 x 5
gear se_mpg se_cyl mpg cyl
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3 0.871 0.307 16.1 7.47
2 4 1.52 0.284 24.5 4.67
3 5 2.98 0.894 21.4 6
为什么会这样?这与我对everything()
的使用有关吗?在我的情况下,我希望对数据集中的每个变量计算出mean
和standard error of the mean
。
解决方法
我不知道为什么summarize
会那样,这可能是由于两个across
函数之间的潜在交互作用(尽管对我来说很奇怪)。无论如何,我建议您编写一个across
语句,并使用across
documentation建议的lambda函数列表。
通过这种方式,将均值或标准差指定为第一个函数都没有关系,您将不会获得NA。
mtcars %>%
group_by(gear) %>%
select(mpg,cyl) %>%
summarize(across(everything(),list(
mean = ~mean(.x,na.rm = TRUE),se = ~sd(.x,na.rm = TRUE)/sqrt(sum(!is.na(.x)))
),.names = "{fn}_{col}"))
# A tibble: 3 x 5
# gear mean_mpg se_mpg mean_cyl se_cyl
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 3 16.1 0.871 7.47 0.307
# 2 4 24.5 1.52 4.67 0.284
# 3 5 21.4 2.98 6 0.894
mtcars %>%
group_by(gear) %>%
select(mpg,list(
se = ~sd(.x,na.rm = TRUE)/sqrt(sum(!is.na(.x))),mean = ~mean(.x,na.rm = TRUE)
),.names = "{fn}_{col}"))
# A tibble: 3 x 5
# gear se_mpg mean_mpg se_cyl mean_cyl
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 3 0.871 16.1 0.307 7.47
# 2 4 1.52 24.5 0.284 4.67
# 3 5 2.98 21.4 0.894 6