Programming with tidyeval: The mutate function after tidyr::unite(col = !!col)

白昼怎懂夜的黑 提交于 2021-02-08 04:54:09

问题


So I want to make a function with unite() from tidyr, but it does not seem to work..

library(dplyr, warn.conflicts = FALSE)
library(tidyr, warn.conflicts = FALSE)
library(stringr, warn.conflicts = FALSE)


mtcars %>% 
  as_tibble() %>% 
  select(mpg , cyl) %>% 
  mutate_all(as.character) %>% 
  unite(col = hello, sep = "/") %>% 
  mutate(hello = str_replace(hello, "/", ""))
#> # A tibble: 32 x 1
#>    hello
#>    <chr>
#>  1 216  
#>  2 216  
#>  3 22.84
#>  4 21.46
#>  5 18.78
#>  6 18.16
#>  7 14.38
#>  8 24.44
#>  9 22.84
#> 10 19.26
#> # ... with 22 more rows



# Now I want to make it a function where I choose the colomn name i unite()
unite_fun <- function(df, var1 = mpg, var2 = cyl, col_name = hello){
  var1 <- enquo(var1)
  var2 <- enquo(var2)
  col_name <- enquo(col_name)

  mtcars %>% 
    as_tibble() %>% 
    select(!!var1 , !!var2) %>% 
    mutate_all(as.character) %>% 
    unite(col = !!col_name, sep = "/") %>% 
    mutate(col_name = str_replace(col_name, "/", "")) # how do I refer to col_name here in mutate


}

Created on 2019-07-12 by the reprex package (v0.3.0)

How do I use the column name I have chosen in unite in mutate?


回答1:


I am not sure if this is the best way to do this but an option is to use quo_name to refer it in mutate

library(tidyverse)
library(rlang)

unite_fun <- function(df, var1 = mpg, var2 = cyl, col_name = hello){
   var1 <- enquo(var1)
   var2 <- enquo(var2)
   col_name <- enquo(col_name)
   col1_name <- quo_name(col_name)

  mtcars %>% 
     as_tibble() %>% 
     select(!!var1 , !!var2) %>% 
     mutate_all(as.character) %>% 
     unite(col = !!col_name, sep = "/")  %>%
     mutate(!!col1_name := str_replace(!!col_name, "/", ""))
}

unite_fun(mtcars, mpg, cyl)
# A tibble: 32 x 1
#   hello
#   <chr>
# 1 216  
# 2 216  
# 3 22.84
# 4 21.46
# 5 18.78
# 6 18.16
# 7 14.38
# 8 24.44
# 9 22.84
#10 19.26
# … with 22 more rows



回答2:


We could make use of the {{..}} - curly-curly operator from rlang -0.4.0 and it should make it more easier to do the evaluation

library(dplyr)
library(rlang)
library(tidyr)
unite_fun <- function(df, var1, var2, col_name = hello){     

  df %>% 
     as_tibble() %>% 
     select({{var1}} , {{var2}}) %>% 
        mutate_all(as.character) %>% 
     unite(col = {{col_name}}, sep = "")  
}

unite_fun(mtcars, mpg, cyl)
# A tibble: 32 x 1
#   hello
#   <chr>
# 1 216  
# 2 216  
# 3 22.84
# 4 21.46
# 5 18.78
# 6 18.16
# 7 14.38
# 8 24.44
# 9 22.84
#10 19.26
# … with 22 more rows

If we need to use the mutate step at the end

unite_fun <- function(df, var1, var2, col_name = hello){


  df %>% 
     as_tibble() %>% 
     select({{var1}} , {{var2}}) %>% 
        mutate_all(as.character) %>% 
     unite(col = {{col_name}}, sep = "/")   %>%
     mutate_at(1, ~ str_replace(., "/", ""))
}

unite_fun(mtcars, mpg, cyl)
# A tibble: 32 x 1
#   hello
#   <chr>
# 1 216  
# 2 216  
# 3 22.84
# 4 21.46
# 5 18.78
# 6 18.16
# 7 14.38
# 8 24.44
# 9 22.84
#10 19.26
# … with 22 more rows


来源:https://stackoverflow.com/questions/57004055/programming-with-tidyeval-the-mutate-function-after-tidyrunitecol-col

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!