Думаю, проблема больше в том, как вы используете аргументы функции. Рассмотрим следующее:
iris %>%
group_by(Species) %>%
summarize(avg_1 = mean(Sepal.Length),
avg_2 = mean(Sepal.Width))
Species avg_1 avg_2
<fct> <dbl> <dbl>
1 setosa 5.01 3.43
2 versicolor 5.94 2.77
3 virginica 6.59 2.97
Обратите внимание, что Sepal.Length
и Sepal.Width
не заключены в двойные кавычки. Это основано на особенностях работы dplyr
и tidyverse
в целом.
Теперь попробуйте следующее:
iris %>%
group_by(Species) %>%
summarize(avg_1 = mean("Sepal.Length"),
avg_2 = mean("Sepal.Width"))
# A tibble: 3 x 3
Species avg_1 avg_2
<fct> <dbl> <dbl>
1 setosa NA NA
2 versicolor NA NA
3 virginica NA NA
Warning messages:
1: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
2: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
3: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
4: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
5: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
6: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
Не работает. По сути, это то, что делает ваша функция.
f <- function(.x, .y) {
iris %>%
group_by(Species) %>%
summarize(avg_1 = mean(.x),
avg_2 = mean(.y))
}
f("Sepal.Length", "Sepal.Width")
# A tibble: 3 x 3
Species avg_1 avg_2
<fct> <dbl> <dbl>
1 setosa NA NA
2 versicolor NA NA
3 virginica NA NA
Warning messages:
1: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
2: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
3: In mean.default("Sepal.Length") :
argument is not numeric or logical: returning NA
4: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
5: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
6: In mean.default("Sepal.Width") :
argument is not numeric or logical: returning NA
Обойти это на самом деле довольно просто, но немного сложнее. Вы можете прочитать об этом здесь, что объяснит это намного лучше, чем я: https://adv-r.hadley.nz/quasiquotation.html.
Но пока вот что должно работать. Я не могу воспроизвести ваш пример, но вы можете применить ту же концепцию.
f <- function(.x, .y) {
.x <- rlang::ensym(.x)
.y <- rlang::ensym(.y)
iris %>%
group_by(Species) %>%
summarize(avg_1 = mean(!!.x),
avg_2 = mean(!!.y))
}
f("Sepal.Length", "Sepal.Width")
# A tibble: 3 x 3
Species avg_1 avg_2
<fct> <dbl> <dbl>
1 setosa 5.01 3.43
2 versicolor 5.94 2.77
3 virginica 6.59 2.97
Другой вариант - использовать местоимение .data
, которое подразумевается в dplyr
.
f <- function(.x, .y) {
iris %>%
group_by(Species) %>%
summarize(avg_1 = mean(.data[[.x]]),
avg_2 = mean(.data[[.y]]))
}