取 dplyr 中字符串定义的变量的平均值
take mean of variable defined by string in dplyr
看起来这应该很容易,但我很难过。我已经掌握了使用 dplyr
0.7 进行编程的粗略技巧,但为此苦苦挣扎:How do I program in dplyr
if the variable I want to program will be a string?
我正在抓取一个数据库,出于各种原因想总结一个我知道位置但不知道名称的变量(我想要的总是提供的第一列table,但存储在该列中的变量的名称将根据被抓取的数据库而有所不同)。以 iris
为例,假设我知道我想要的变量在第一列
library(tidyverse)
desired_var <- colnames(iris)[1]
print(desired_var)
"Sepal.Length"
我现在想按Species
分组,取desired_var
的平均值,即我要执行的是
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(Sepal.Length))
但是,现在我想取由存储在 desired_var
中的字符串定义的列的平均值
我知道如何使用 "bare" Sepal.Length
desired_var <- quo(Sepal.Length)
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(!!desired_var))
但是我到底该如何处理 "Sepal.Length"
而不是 Sepal.Length
的事实,即 desired_var <- "Sepal.Length"
?
您想了解 tidyeval
,这是 tidyverse
(参见 here)的一项相当新的功能,更多用于使用 tidyverse
函数创建函数。目前它仅适用于 dplyr
,但计划将其扩展到其他 tidyverse
包。
不过,根据您的需要,您真的不需要深入了解,summarize_at
就可以了。此函数允许您扩展您在所选的任何变量中指定的特定操作:
iris %>%
group_by(Species) %>%
summarise_at(vars(one_of("Sepal.Length", "Sepal.Width")), funs(desired_mean = mean))
# A tibble: 3 x 3
Species Sepal.Length_desired_mean Sepal.Width_desired_mean
<fctr> <dbl> <dbl>
1 setosa 5.006 3.428
2 versicolor 5.936 2.770
3 virginica 6.588 2.974
您可以将变量列表存储到向量中,然后改用该向量:
selected_vectors <- c("Sepal.Length", "Sepal.Width")
iris %>%
group_by(Species) %>%
summarise_at(vars(one_of(selected_vectors)), funs(desired_mean = mean))
1) 带有 !!sym 的动态变量 使用 sym
(或 parse_expr
),如下所示:
library(dplyr)
library(rlang)
desired_var <- "Sepal.Length"
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(!!sym(desired_var))) %>%
ungroup
给予:
# A tibble: 3 x 2
Species desired_mean
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
2) summarise_at 正如@Phil 在 summarise
的特殊情况下的评论中指出的那样,可以在不使用任何 rlang 的情况下这样做设施:
library(dplyr)
desired_var <- "Sepal.Length"
iris %>%
group_by(Species) %>%
summarise_at(desired_var, funs(mean)) %>%
ungroup
给予:
# A tibble: 3 x 2
Species Sepal.Length
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
3) 带!! 的动态变量和名称 如果您需要在 (1) 中动态设置名称,那么试试这个:
library(dplyr)
library(rlang)
desired_var <- "Sepal.Length"
desired_var_name <- paste("mean", desired_var, sep = "_")
iris %>%
group_by(Species) %>%
summarise(!!desired_var_name := mean(!!sym(desired_var))) %>%
ungroup
给予:
# A tibble: 3 x 2
Species mean_Sepal.Length
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
看起来这应该很容易,但我很难过。我已经掌握了使用 dplyr
0.7 进行编程的粗略技巧,但为此苦苦挣扎:How do I program in dplyr
if the variable I want to program will be a string?
我正在抓取一个数据库,出于各种原因想总结一个我知道位置但不知道名称的变量(我想要的总是提供的第一列table,但存储在该列中的变量的名称将根据被抓取的数据库而有所不同)。以 iris
为例,假设我知道我想要的变量在第一列
library(tidyverse)
desired_var <- colnames(iris)[1]
print(desired_var)
"Sepal.Length"
我现在想按Species
分组,取desired_var
的平均值,即我要执行的是
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(Sepal.Length))
但是,现在我想取由存储在 desired_var
我知道如何使用 "bare" Sepal.Length
desired_var <- quo(Sepal.Length)
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(!!desired_var))
但是我到底该如何处理 "Sepal.Length"
而不是 Sepal.Length
的事实,即 desired_var <- "Sepal.Length"
?
您想了解 tidyeval
,这是 tidyverse
(参见 here)的一项相当新的功能,更多用于使用 tidyverse
函数创建函数。目前它仅适用于 dplyr
,但计划将其扩展到其他 tidyverse
包。
不过,根据您的需要,您真的不需要深入了解,summarize_at
就可以了。此函数允许您扩展您在所选的任何变量中指定的特定操作:
iris %>%
group_by(Species) %>%
summarise_at(vars(one_of("Sepal.Length", "Sepal.Width")), funs(desired_mean = mean))
# A tibble: 3 x 3
Species Sepal.Length_desired_mean Sepal.Width_desired_mean
<fctr> <dbl> <dbl>
1 setosa 5.006 3.428
2 versicolor 5.936 2.770
3 virginica 6.588 2.974
您可以将变量列表存储到向量中,然后改用该向量:
selected_vectors <- c("Sepal.Length", "Sepal.Width")
iris %>%
group_by(Species) %>%
summarise_at(vars(one_of(selected_vectors)), funs(desired_mean = mean))
1) 带有 !!sym 的动态变量 使用 sym
(或 parse_expr
),如下所示:
library(dplyr)
library(rlang)
desired_var <- "Sepal.Length"
iris %>%
group_by(Species) %>%
summarise(desired_mean = mean(!!sym(desired_var))) %>%
ungroup
给予:
# A tibble: 3 x 2
Species desired_mean
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
2) summarise_at 正如@Phil 在 summarise
的特殊情况下的评论中指出的那样,可以在不使用任何 rlang 的情况下这样做设施:
library(dplyr)
desired_var <- "Sepal.Length"
iris %>%
group_by(Species) %>%
summarise_at(desired_var, funs(mean)) %>%
ungroup
给予:
# A tibble: 3 x 2
Species Sepal.Length
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
3) 带!! 的动态变量和名称 如果您需要在 (1) 中动态设置名称,那么试试这个:
library(dplyr)
library(rlang)
desired_var <- "Sepal.Length"
desired_var_name <- paste("mean", desired_var, sep = "_")
iris %>%
group_by(Species) %>%
summarise(!!desired_var_name := mean(!!sym(desired_var))) %>%
ungroup
给予:
# A tibble: 3 x 2
Species mean_Sepal.Length
<fctr> <dbl>
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588