Как написать use quos в формуле в R?

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

Я думал, что могу написать что-то вроде этого:

A <- data.frame(x = 1:5, y = 11:15)

f <- function(x, y, new) {
  x_quo <- rlang::enquo(x)
  y_quo <- rlang::enquo(y)
  new_quo <- rlang::enquo(new)
  A %<>% mutate (!!new_quo := !!x_quo * !!y_quo)
  A
}

f("x", "y", "new")

Я ожидал, что это будет эквивалентно запуску этого кода:

A <- data.frame(x = 1:5, y = 11:15)
A %<>% mutate (new = x * y);

Однако, но когда я запускаю этот первый код, я получаю эту ошибку:

 Error: Problem with `mutate()` input `new`.
 x non-numeric argument to binary operator
 i Input `new` is `"x" * "y"`.
 Run `rlang::last_error()` to see where the error occurred. 

Что означает эта ошибка? Есть ли способ создать функцию, как я описал?


person ClownsENT    schedule 22.06.2020    source источник
comment
Не могли бы вы опубликовать воспроизводимую проблему, пожалуйста? Сообществу сложно понять проблему, если мы не можем воспроизвести ее сами. См. stackoverflow.com/questions/5963269/   -  person geotheory    schedule 22.06.2020
comment
Сообщение об ошибке показывает, что вы пытаетесь умножить строки. Вам нужно преобразовать их в языковые объекты, прежде чем раскачивать, либо с помощью sym(), либо parse_expr()   -  person Lionel Henry    schedule 22.06.2020
comment
@geotheory конечно! Я изменил это, чтобы быть (как я думаю) воспроизводимой проблемой, которая, я думаю, все еще отражает проблему. Дайте мне знать, если вы считаете, что мне нужно предоставить дополнительную информацию.   -  person ClownsENT    schedule 22.06.2020
comment
@LionelHenry спасибо, теперь работает! Могу ли я как-то отметить ваш ответ как правильный? (извините за мое невежество здесь).   -  person ClownsENT    schedule 22.06.2020


Ответы (1)


Попробуйте использовать sym и оцените его с помощью !!. Я бы также передал в функцию дополнительный аргумент данных.

library(dplyr)
library(rlang)

f <- function(data, x, y, new) {
  data %>% mutate (!!new := !!sym(x) * !!sym(y))
}

A %>% f("x", "y", "new")

#  x  y new
#1 1 11  11
#2 2 12  24
#3 3 13  39
#4 4 14  56
#5 5 15  75

identical(A %>% f("x", "y", "new"), A %>% mutate (new = x * y))
#[1] TRUE
person Ronak Shah    schedule 22.06.2020
comment
Хороший ответ. Кстати, теперь рекомендуется избегать раскавычек, потому что это сложно понять новичкам. Вместо этого вы можете использовать синтаксис клея в левой части := и местоимение .data в правой части: mutate("{new}" := .data[[x]] * .data[[y]])) - person Lionel Henry; 23.06.2020