简体   繁体   中英

Behavior as.list in rlang::enexpr() in R

I try to think there is any way I can have multiple variables for each argument. If I used ensyms , I can't have a vector like I provided in function, but I would love to have the function works for both way groups = c(am, vs) or groups = c("am", "vs")

The first 2 giving me 2 more columns if I used groups = c("am", "vs") , the last two are working correctly if I used groups = c(am, vs) . The selected_var is working correctly either I used select_vars = c( "mpg","disp") or select_vars = c( mpg, disp)

Any idea will help?

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.

It seems like this will do what you need

tryfn <- function(data, select_vars, groups){
  
  data %>% 
    select({{groups}}, {{select_vars}}) %>% 
    group_by(across({{groups}}))
  
}

We use across() with the group_by to expand the multiple selection.

I add one line group_vars <- purrr::map(group_vars, as.symbol) to your function. This makes sure that the items in group_vars will turn into symbols.

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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM