【问题标题】:Programming with tidyeval: The mutate function after tidyr::unite(col = !!col)使用 tidyeval 编程:tidyr::unite(col = !!col) 之后的 mutate 函数
【发布时间】:2019-07-12 09:24:32
【问题描述】:

所以我想用 tidyr 的unite() 做一个函数,但它似乎不起作用..

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


}

reprex package (v0.3.0) 于 2019-07-12 创建

如何使用我在 unite in mutate 中选择的列名?

【问题讨论】:

  • unite(col = !!col_name, sep = "/")?
  • @r.user.05apr:谢谢,我已经有了一个新问题。你能再看看这个问题吗?我想使用我在mutate 中选择的列名。
  • Ronak 更快(可能使用ensym 而不是enquo,因为列名是“唯一”符号,似乎是变量的另一个名称)。

标签: r dplyr tidyr rlang tidyeval


【解决方案1】:

我不确定这是否是最好的方法,但可以选择使用quo_namemutate 中引用它

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】:

    我们可以使用 {{..}} - 来自 rlang -0.4.0 的 curly-curly 运算符,它应该更容易进行评估

    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
    

    如果我们需要在最后使用mutate 步骤

    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
    

    【讨论】:

    • @David 我认为这是多余的步骤
    • @David 不管怎样,我根据你的 cmets 更新了我的帖子
    猜你喜欢
    • 2019-03-13
    • 2019-04-15
    • 2018-09-09
    • 2016-02-13
    • 1970-01-01
    • 2018-12-21
    • 2020-05-31
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多