【问题标题】:Access the column names in the `mutate_at` to use it for subseting a list访问 `mutate_at` 中的列名以将其用于子集列表
【发布时间】:2020-04-30 12:16:40
【问题描述】:

我正在尝试重新编码几个变量,但使用不同的重新编码方案。 重新编码方案保存在一个列表中,其中每个元素都是old = new 形式的命名向量。 每个元素是数据框中每个变量的重新编码方案

我正在使用mutate_at 函数和recode

我认为问题在于我无法提取变量名称以使用它从列表中获取正确的重新编码方案

我试过deparse(substitute(.)) 就像here 还有this 没有帮助

我还看到here,我可以提取通过 tidyevalution 传递的变量的列名,但我再次未能实现它。 (它也在使用已弃用的“乐趣”)

最后,我希望这是重新编码变量的正确方法(即在 mutate 中使用此重新编码列表)。如果有完全不同的方法来处理这种多重重新编码,请告诉我

library(dplyr)
# dplyr version 0.8.5

df <- 
  tibble(
    var1 = c("A", "A", "B", "C"),
    var2 = c("X", "Y", "Z", "Z")
  )

recode_list <- 
  list(

    var1 = c(A = 1, B = 2, C = 3),
    var2 = c(X = 0, Y = -1, Z = 1)
  )

recode_list
#> $var1
#> A B C 
#> 1 2 3 
#> 
#> $var2
#>  X  Y  Z 
#>  0 -1  1

我正在使用dplyr::recode 函数。


# recoding works fine when doing it one variable as a time
df %>% 
  mutate(
    var1 = recode(var1, !!!recode_list[["var1"]]),
    var2 = recode(var2, !!!recode_list[["var2"]])
  )
#> # A tibble: 4 x 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     0
#> 2     1    -1
#> 3     2     1
#> 4     3     1

当我尝试为所有变量应用一个函数时,它似乎失败了

# this does not work.
df %>%
  mutate_at(vars(var1, var2), ~{

    var_name <- rlang::quo_name(quo(.))

    recode(., !!!recode_list[[var_name]])
  }
  )
#> Error in expr_interp(f): object 'var_name' not found

我也尝试过rlang::as_namerlang::as_label,但我认为我无法真正将变量的名称捕获为字符串以使用它来子集recode_list


df %>%
  mutate_at(vars(var1, var2), ~ {
    var_name <- rlang::as_name(quo(.))
    print(var_name)
    #recode(., !!!recode_list[["var2"]])
  }
  )
#> [1] "."
#> [1] "."
#> # A tibble: 4 x 2
#>   var1  var2 
#>   <chr> <chr>
#> 1 .     .    
#> 2 .     .    
#> 3 .     .    
#> 4 .     .


Created on 2020-04-30 by the reprex package (v0.3.0)

【问题讨论】:

    标签: r dplyr tidyeval


    【解决方案1】:

    这对你有用吗?

    library(dplyr)
    library(rlang)
    df %>% 
      mutate_at(vars(var1,var2),
                .funs = function(x){recode_list %<>% .[[as_label(enquo(x))]]
                recode(x,!!!recode_list)})
    ## A tibble: 4 x 2
    #   var1  var2
    #  <dbl> <dbl>
    #1     1     0
    #2     1    -1
    #3     2     1
    #4     3     1
    

    我怀疑这在将子集 recode_list 直接放入 recode 时不起作用是因为 enquo 延迟了对 x 的评估,直到分配给 %&lt;&gt;%。然后!!! 可以在之前正确评估后强制评估。

    编辑

    您使用rlang 的方法也适用于一些修改:

    library(rlang)
    df %>%
      mutate_at(vars(var1, var2), function(x) {
        var_name <- rlang::as_label(substitute(x))
        recode(x, !!!recode_list[[var_name]])
      })
    

    【讨论】:

    • 谢谢@Ian!有用!非常感激! (我仍然不明白为什么我们应该使用enquo(或基础R 中的substitute)而不是quo。还有为什么function(x) 有效而~ 无效)
    • 另外,quo_name 已被弃用,您可以将其替换为 as_nameas_label。再次感谢!
    • 总的来说,我认为阻止你的是.funs = list(~{})的非标准评价,我承认,我不完全理解。当它没有按我预期的方式工作时,我只是回到经典的function(x){} 表单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多