Переименование столбца в tidyeval в dplyr 1.0

#r #dplyr #tidyverse #rlang #tidyeval

#r #dplyr #tidyverse #rlang #tidyeval

Вопрос:

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

 library(dplyr)

some_custom_measure <- function(.data, cola, colb) {
    .data %>% mutate("{{ cola }}_x_{{ colb }}" := {{ cola }} * {{ colb }})
}
iris %>% 
    some_custom_measure(Sepal.Length, Sepal.Width) %>% 
    head()
 

Новый столбец будет назван Sepal.Length_x_Sepal.Width .

Как мне манипулировать переменными как строкой при формировании нового имени в пользовательской функции? Я хочу выполнить что-то вроде sepal_length_x_sepal_width

Ответ №1:

Вы можете использовать deparse(substitute(...)) для записи каждого имени переменной в виде строки и сохранения его в переменной.

Затем вы можете обработать эту переменную так, как вам нравится манипулировать строкой. Когда вы начнете его использовать, поместите переменную в одиночные фигурные скобки в спецификации имени столбца.

 library(dplyr)

some_custom_measure <- function(.data, cola, colb) {

    cola_name <- tolower(gsub("\.", "_", deparse(substitute(cola))))
    colb_name <- tolower(gsub("\.", "_", deparse(substitute(colb))))

    .data %>% mutate("{cola_name}_x_{colb_name}" := {{ cola }} * {{ colb }})
}

iris %>% 
    some_custom_measure(Sepal.Length, Sepal.Width) %>% 
    head()
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
#>   sepal_length_x_sepal_width
#> 1                      17.85
#> 2                      14.70
#> 3                      15.04
#> 4                      14.26
#> 5                      18.00
#> 6                      21.06
 

Комментарии:

1. Спасибо! Кроме того, я выяснил, что as_name(enquo(...)) в rlang

2. Я рекомендую использовать rlang::as_label() which, в отличие deparse() от , гарантированно возвращает строку длиной 1. rlang::as_name() Вариант дополнительно проверяет, что ввод представляет собой одно имя, тогда as_label() как работает с любым выражением.