Получите доступ к именам столбцов в `mutate_at`, чтобы использовать их для размещения списка - PullRequest
3 голосов
/ 30 апреля 2020

Я пытаюсь перекодировать несколько переменных, но с разными схемами перекодирования. Схема перекодирования сохраняется в списке, где каждый элемент является именованным вектором вида old = new. Каждый элемент является схемой перекодирования для каждой переменной в кадре данных

Я использую функцию mutate_at и recode.

Я думаю, что проблема в том, что я не могу извлечь имя переменной, чтобы использовать его для получения правильной схемы перекодирования из списка

Я пытался deparse(substitute(.)), как в здесь , а также this не помогло

Также я увидел здесь , что я могу извлечь имя столбца переменной, которая передается с помощью tidyevaluation, но мне снова не удалось его реализовать. (также он использует устаревшие '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_name и rlang::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)

1 Ответ

1 голос
/ 30 апреля 2020

Работает ли это для вас?

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]])
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...