Как оценить построенную строку с нестандартной оценкой, используя dplyr?

Я прочитал несколько руководств по программированию с помощью dplyr сейчас, и я все еще не уверен, как решить проблему оценки построенных / сцепленных строк с помощью нестандартной оценки (NSE). Я понимаю, что есть лучшие способы решить этот пример, чем использовать NSE, но хочу научиться этому.

t <- tibble( x_01 = c(1, 2, 3), x_02 = c(4, 5, 6))
i <- 1

Это мой желаемый результат, но хочу, чтобы переменные в mutate() быть построенным:

t %>% mutate(d_01 = x_01 * 2)
#>   A tibble: 3 x 3
#>   x_01  x_02  d_01
#>   <dbl> <dbl> <dbl>
#> 1  1.00  4.00  2.00
#> 2  2.00  5.00  4.00
#> 3  3.00  6.00  6.00

Это моя первая попытка использования строк:

new <- sprintf("d_%02d", i)
var <- sprintf("x_%02d", i)
t %>% mutate(new = var * 2)
#> Error in mutate_impl(.data, dots) : 
#> Evaluation error: non-numeric argument to binary operator.

Это моя вторая попытка, пытаясь использовать вопросы:

new <- rlang::quo(sprintf("d_%02d", i))
var <- rlang::quo(sprintf("x_%02d", i))
t %>% mutate(!!new = !!var * 2)
#> Error: unexpected '=' in "t %>% mutate(!!new ="

Это моя третья попытка использовать := оператор:

new <- rlang::quo(sprintf("d_%02d", i))
var <- rlang::quo(sprintf("x_%02d", i))
t %>% mutate(!!new := !!var * 2)
#> Error in var * 2 : non-numeric argument to binary operator

2 ответа

Решение

Использование sym а также := как это:

library(dplyr)
library(rlang)

t <- tibble( x_01 = c(1, 2, 3), x_02 = c(4, 5, 6))
i <- 1

new <- sym(sprintf("d_%02d", i))
var <- sym(sprintf("x_%02d", i))
t %>% mutate(!!new := (!!var) * 2)

давая:

# A tibble: 3 x 3
   x_01  x_02  d_01
  <dbl> <dbl> <dbl>
1     1     4     2
2     2     5     4
3     3     6     6

Также обратите внимание, что это тривиально в базе R:

tdf <- data.frame( x_01 = c(1, 2, 3), x_02 = c(4, 5, 6))
i <- 1

new <- sprintf("d_%02d", i)
var <- sprintf("x_%02d", i)
tdf[[new]] <- 2 * tdf[[var]]

Вы можете найти пакет friendlyevalполезно при изучении приборки eval. Это упрощает API и делает выбор функций понятным в подобных случаях.

У вас есть две строки, которые вы хотите использовать в качестве имен столбцов, поэтому вы можете написать:

t <- tibble( x_01 = c(1, 2, 3), x_02 = c(4, 5, 6))
i <- 1

new <- sprintf("d_%02d", i)
var <- sprintf("x_%02d", i)
t %>% mutate(!!treat_string_as_col(new) := 
               !!treat_string_as_col(var) * 2)

Вы можете конвертировать из friendlyeval код в простой и понятный код в любое время с помощью надстройки RStudio. Это может быть полезно с учетом вашей учебной цели.

Другие вопросы по тегам