访问 `mutate_at` 中的列名称以使用它来对列表进行子集化

Access the column names in the `mutate_at` to use it for subseting a list

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

我正在使用 mutate_at 函数和 recode

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

我试过 deparse(substitute(.)) 一样 而且 没有帮助

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

最后,我希望这是重新编码变量的正确方法(即在 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)

这对你有用吗?

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 的评估,直到用 %<>% 赋值.然后 !!! 可以在之前正确评估后强制评估。

编辑

您使用 rlang 的方法经过一些修改后也适用:

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