R 中 rlang::enexpr() 中的行为 as.list
Behavior as.list in rlang::enexpr() in R
我试着想有什么方法可以为每个参数设置多个变量。如果我使用 ensyms
,我不能像我在函数中提供的那样拥有一个向量,但我希望该函数同时适用于 groups = c(am, vs)
或 groups = c("am", "vs")
如果我使用 groups = c("am", "vs")
,前 2 列会多出 2 列,如果我使用 groups = c(am, vs)
,则后两列可以正常工作。我使用 select_vars = c( "mpg","disp")
或 select_vars = c( mpg, disp)
selected_var 工作正常
有什么想法可以帮助吗?
tryfn <- function(data, select_vars,groups, ...){
select_vars <- as.list(rlang::enexpr(select_vars ))
select_vars <- if(length(select_vars) > 1) select_vars[-1] else select_vars
group_vars <- as.list(rlang::enexpr(groups))
group_vars <- if(length(group_vars ) > 1) group_vars[-1] else group_vars
data %>% select(!!!group_vars,!!!select_vars) %>% group_by(!!!group_vars)
}
# If I used groups argument as string, it gave me 2 extra columns
tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c("am", "vs"))
tryfn(mtcars, select_vars = c( mpg, disp), groups = c("am", "vs"))
> tryfn(mtcars, select_vars = c( mpg, disp), groups = c("am", "vs"))
# A tibble: 32 x 6
# Groups: "am", "vs" [1]
am vs mpg disp **`"am"` `"vs"`**
<dbl> <dbl> <dbl> <dbl> <chr> <chr>
1 1 0 21 160 am vs
2 1 0 21 160 am vs
3 1 1 22.8 108 am vs
4 0 1 21.4 258 am vs
5 0 0 18.7 360 am vs
6 0 1 18.1 225 am vs
7 0 0 14.3 360 am vs
8 0 1 24.4 147. am vs
9 0 1 22.8 141. am vs
10 0 1 19.2 168. am vs
# this one is working perfectly
tryfn(mtcars, select_vars = c( mpg, disp), groups = c(am, vs))
tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c(am, vs))
> tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c(am, vs))
# A tibble: 32 x 4
# Groups: am, vs [4]
am vs mpg disp
* <dbl> <dbl> <dbl> <dbl>
1 1 0 21 160
2 1 0 21 160
3 1 1 22.8 108
4 0 1 21.4 258
5 0 0 18.7 360
6 0 1 18.1 225
7 0 0 14.3 360
8 0 1 24.4 147.
9 0 1 22.8 141.
10 0 1 19.2 168.
看来这会满足您的需求
tryfn <- function(data, select_vars, groups){
data %>%
select({{groups}}, {{select_vars}}) %>%
group_by(across({{groups}}))
}
我们使用across()
配合group_by
来展开多选
我给你的函数加了一行group_vars <- purrr::map(group_vars, as.symbol)
。这确保 group_vars
中的项目将变成符号。
tryfn <- function(data, select_vars,groups, ...){
select_vars <- as.list(rlang::enexpr(select_vars))
select_vars <- if(length(select_vars) > 1) select_vars[-1] else select_vars
group_vars <- as.list(rlang::enexpr(groups))
group_vars <- if(length(group_vars ) > 1) group_vars[-1] else group_vars
group_vars <- purrr::map(group_vars, as.symbol)
data %>% select(!!!group_vars,!!!select_vars) %>% group_by(!!!group_vars)
}
我试着想有什么方法可以为每个参数设置多个变量。如果我使用 ensyms
,我不能像我在函数中提供的那样拥有一个向量,但我希望该函数同时适用于 groups = c(am, vs)
或 groups = c("am", "vs")
如果我使用 groups = c("am", "vs")
,前 2 列会多出 2 列,如果我使用 groups = c(am, vs)
,则后两列可以正常工作。我使用 select_vars = c( "mpg","disp")
或 select_vars = c( mpg, disp)
有什么想法可以帮助吗?
tryfn <- function(data, select_vars,groups, ...){
select_vars <- as.list(rlang::enexpr(select_vars ))
select_vars <- if(length(select_vars) > 1) select_vars[-1] else select_vars
group_vars <- as.list(rlang::enexpr(groups))
group_vars <- if(length(group_vars ) > 1) group_vars[-1] else group_vars
data %>% select(!!!group_vars,!!!select_vars) %>% group_by(!!!group_vars)
}
# If I used groups argument as string, it gave me 2 extra columns
tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c("am", "vs"))
tryfn(mtcars, select_vars = c( mpg, disp), groups = c("am", "vs"))
> tryfn(mtcars, select_vars = c( mpg, disp), groups = c("am", "vs"))
# A tibble: 32 x 6
# Groups: "am", "vs" [1]
am vs mpg disp **`"am"` `"vs"`**
<dbl> <dbl> <dbl> <dbl> <chr> <chr>
1 1 0 21 160 am vs
2 1 0 21 160 am vs
3 1 1 22.8 108 am vs
4 0 1 21.4 258 am vs
5 0 0 18.7 360 am vs
6 0 1 18.1 225 am vs
7 0 0 14.3 360 am vs
8 0 1 24.4 147. am vs
9 0 1 22.8 141. am vs
10 0 1 19.2 168. am vs
# this one is working perfectly
tryfn(mtcars, select_vars = c( mpg, disp), groups = c(am, vs))
tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c(am, vs))
> tryfn(mtcars, select_vars = c( "mpg","disp"), groups = c(am, vs))
# A tibble: 32 x 4
# Groups: am, vs [4]
am vs mpg disp
* <dbl> <dbl> <dbl> <dbl>
1 1 0 21 160
2 1 0 21 160
3 1 1 22.8 108
4 0 1 21.4 258
5 0 0 18.7 360
6 0 1 18.1 225
7 0 0 14.3 360
8 0 1 24.4 147.
9 0 1 22.8 141.
10 0 1 19.2 168.
看来这会满足您的需求
tryfn <- function(data, select_vars, groups){
data %>%
select({{groups}}, {{select_vars}}) %>%
group_by(across({{groups}}))
}
我们使用across()
配合group_by
来展开多选
我给你的函数加了一行group_vars <- purrr::map(group_vars, as.symbol)
。这确保 group_vars
中的项目将变成符号。
tryfn <- function(data, select_vars,groups, ...){
select_vars <- as.list(rlang::enexpr(select_vars))
select_vars <- if(length(select_vars) > 1) select_vars[-1] else select_vars
group_vars <- as.list(rlang::enexpr(groups))
group_vars <- if(length(group_vars ) > 1) group_vars[-1] else group_vars
group_vars <- purrr::map(group_vars, as.symbol)
data %>% select(!!!group_vars,!!!select_vars) %>% group_by(!!!group_vars)
}