如何让整洁的点接受可变范围
How to get tidy dots to accept a variable range
我发现这个 very helpful article 关于如何使用 quosure 和 tidy dots 编写接受变量参数的函数。这是一些代码:
my.summary <- function(df.name=df_tp1, group_var, ...) {
group_var <- enquo(group_var)
smry_vars <- enquos(..., .named = TRUE)
the.mean <- purrr::map(smry_vars, function(var) {
expr(mean(!!var, na.rm = TRUE))
})
names(the.mean) <- paste0("mean-", names(the.mean))
df.name %>%
group_by(!!group_var) %>%
summarise(!!!the.mean)
}
问题是我必须用一长串变量调用函数,如下所示:
cm_all1 <- my.summary(df_tp1_cm, group_var=net_role, so_part_value, cult_ci, cult_sn, cult_ebc, sl_t_lrn, sl_xt_lrn, nl_netops_km, so_rt, nl_netops_trust)
我很高兴能够用
之类的东西来调用它
so_part_value:nl_netops_trust
相反,但这会产生如下错误:
Error in so_part_value:nl_netops_trust : NA/NaN argument
我还尝试将变量名放入字符向量中,然后使用 enquo() 和 !!但这没有用。
如果有任何想法,我将不胜感激。
这里是我根据一夫的思路改写的函数。这适用于我的假数据集,但不适用于真实数据。
my.summary <- function(df.name=df_tp1, group_var, ...) {
## group_var <- enquo(group_var)
smry_vars <- df.name %>% select(...) %>% colnames()
df.name %>%
## group_by(!!group_var) %>%
group_by({{group_var}}) %>%
summarise_at(smry_vars,
list(mean=function(x) mean(x, na.rm=TRUE),
sd=function(x) sd(x, na.rm=TRUE),
min=function(x) min(x, na.rm=TRUE),
max=function(x) max(x, na.rm=TRUE),
q1=function(x) quantile(x, .25, na.rm=TRUE),
q2=function(x) quantile(x, .50, na.rm=TRUE),
q3=function(x) quantile(x, .75, na.rm=TRUE),
n=function(x) n()
))
}
您只需要确保 ...
处于正确的环境中(您在此示例中提供的 df
)。然后你可以使用 colnames()
来提取列名。
library(rlang)
get_column_range <- function(df,...){
writeLines("Column names as string:")
print(df %>% select(...) %>% colnames())
writeLines("Convert back to symbols")
print(syms(df %>% select(...) %>% colnames()))
}
get_column_range(df = iris,Sepal.Length:Petal.Width)
Column names as string:
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
Convert to symbol
[[1]]
Sepal.Length
[[2]]
Sepal.Width
[[3]]
Petal.Length
[[4]]
Petal.Width
和 dplyr
后缀为 _at
的函数也接受字符串作为变量,您不必将它们转换为 quosure 然后取消引用它们。
请注意 {{}}
是一种更容易学习的语法,它同时引用和取消引用:
my.summary <- function(df,group_var,...){
column_names <- df %>% select(...) %>% colnames()
df %>%
group_by({{group_var}}) %>%
summarise_at(column_names,list(mean = mean))
}
my.summary(df = iris,group_var = Species,Sepal.Length:Petal.Width)
# A tibble: 3 x 5
Species Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 3.43 1.46 0.246
2 versicolor 5.94 2.77 4.26 1.33
3 virginica 6.59 2.97 5.55 2.03
我发现这个 very helpful article 关于如何使用 quosure 和 tidy dots 编写接受变量参数的函数。这是一些代码:
my.summary <- function(df.name=df_tp1, group_var, ...) {
group_var <- enquo(group_var)
smry_vars <- enquos(..., .named = TRUE)
the.mean <- purrr::map(smry_vars, function(var) {
expr(mean(!!var, na.rm = TRUE))
})
names(the.mean) <- paste0("mean-", names(the.mean))
df.name %>%
group_by(!!group_var) %>%
summarise(!!!the.mean)
}
问题是我必须用一长串变量调用函数,如下所示:
cm_all1 <- my.summary(df_tp1_cm, group_var=net_role, so_part_value, cult_ci, cult_sn, cult_ebc, sl_t_lrn, sl_xt_lrn, nl_netops_km, so_rt, nl_netops_trust)
我很高兴能够用
之类的东西来调用它so_part_value:nl_netops_trust
相反,但这会产生如下错误:
Error in so_part_value:nl_netops_trust : NA/NaN argument
我还尝试将变量名放入字符向量中,然后使用 enquo() 和 !!但这没有用。
如果有任何想法,我将不胜感激。
这里是我根据一夫的思路改写的函数。这适用于我的假数据集,但不适用于真实数据。
my.summary <- function(df.name=df_tp1, group_var, ...) {
## group_var <- enquo(group_var)
smry_vars <- df.name %>% select(...) %>% colnames()
df.name %>%
## group_by(!!group_var) %>%
group_by({{group_var}}) %>%
summarise_at(smry_vars,
list(mean=function(x) mean(x, na.rm=TRUE),
sd=function(x) sd(x, na.rm=TRUE),
min=function(x) min(x, na.rm=TRUE),
max=function(x) max(x, na.rm=TRUE),
q1=function(x) quantile(x, .25, na.rm=TRUE),
q2=function(x) quantile(x, .50, na.rm=TRUE),
q3=function(x) quantile(x, .75, na.rm=TRUE),
n=function(x) n()
))
}
您只需要确保 ...
处于正确的环境中(您在此示例中提供的 df
)。然后你可以使用 colnames()
来提取列名。
library(rlang)
get_column_range <- function(df,...){
writeLines("Column names as string:")
print(df %>% select(...) %>% colnames())
writeLines("Convert back to symbols")
print(syms(df %>% select(...) %>% colnames()))
}
get_column_range(df = iris,Sepal.Length:Petal.Width)
Column names as string:
[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
Convert to symbol
[[1]]
Sepal.Length
[[2]]
Sepal.Width
[[3]]
Petal.Length
[[4]]
Petal.Width
和 dplyr
后缀为 _at
的函数也接受字符串作为变量,您不必将它们转换为 quosure 然后取消引用它们。
请注意 {{}}
是一种更容易学习的语法,它同时引用和取消引用:
my.summary <- function(df,group_var,...){
column_names <- df %>% select(...) %>% colnames()
df %>%
group_by({{group_var}}) %>%
summarise_at(column_names,list(mean = mean))
}
my.summary(df = iris,group_var = Species,Sepal.Length:Petal.Width)
# A tibble: 3 x 5
Species Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 3.43 1.46 0.246
2 versicolor 5.94 2.77 4.26 1.33
3 virginica 6.59 2.97 5.55 2.03