Tidyeval со списком имен столбцов в функции
Я пытаюсь создать функцию, которая передает список имен столбцов в dplyr
функция. Я знаю, как это сделать, если список имен столбцов приведен в ...
форма, как объяснено в tidyeval
документация:
df <- tibble(
g1 = c(1, 1, 2, 2, 2),
g2 = c(1, 2, 1, 2, 1),
a = sample(5),
b = sample(5)
)
my_summarise <- function(df, ...) {
group_var <- quos(...)
df %>%
group_by(!!!group_var) %>%
summarise(a = mean(a))
}
my_summarise(df, g1, g2)
Но если я хочу перечислить имена столбцов в качестве аргумента функции, приведенное выше решение не будет работать (конечно):
my_summarise <- function(df, group_var, sum_var) {
group_var <- quos(group_var) # nor enquo(group_var)
sum_var <- enquo(sum_var)
df %>%
group_by(!!!group_var) %>%
summarise(a = mean(a))
}
my_summarise(df, list(g1, g2), a)
my_summarise(df, list(g1, g2), b)
Как я могу получить элементы в списке для индивидуального цитирования?
Этот вопрос аналогичен передаче имен столбцов dataframe в функции внутри другой функции, но в комментариях было предложено использовать строки, в то время как здесь я хотел бы использовать голые имена столбцов.
2 ответа
Вы можете передать свой список аргументов, используя alist
вместо list
, поскольку это не будет оценивать аргументы.
my_summarise = function(df, group_var, sum_var) {
group_var = quos(!!! group_var)
sum_var = enquo(sum_var)
df %>%
group_by(!!! group_var) %>%
summarise(!! quo_name( sum_var) := mean( !! sum_var) )
}
my_summarise(df, alist(g1, g2), b)
# A tibble: 4 x 3
# Groups: g1 [?]
g1 g2 b
<dbl> <dbl> <dbl>
1 1 1 2.0
2 1 2 3.0
3 2 1 4.5
4 2 2 1.0
Другой альтернативой было бы передать этот аргумент непосредственно quos
вместо list
как показано в этом ответе, который обходит некоторые осложнения все вместе.
my_summarise = function(df, group_var, sum_var) {
# group_var = quos(!!! group_var)
sum_var = enquo(sum_var)
df %>%
group_by(!!! group_var) %>%
summarise(!! quo_name( sum_var) := mean( !! sum_var) )
}
my_summarise(df, quos(g1, g2), b)
# A tibble: 4 x 3
# Groups: g1 [?]
g1 g2 b
<dbl> <dbl> <dbl>
1 1 1 2.0
2 1 2 3.0
3 2 1 4.5
4 2 2 1.0
library(dplyr)
df <- tibble(
g1 = c(1, 1, 2, 2, 2),
g2 = c(1, 2, 1, 2, 1),
a = sample(5),
b = sample(5)
)
my_summarise = function(df, group_var, fun_name) {
df %>%
group_by(!!! group_var) %>%
summarize_all(fun_name)
}
my_summarise(df, alist(g1, g2), mean)
alist() обрабатывает аргументы 'g1' и 'g2' как аргументы функции (не оценивает их), в то время как!!! (Так же, как UQS(), заключает в кавычки и склеивает список. sum_var не является необходимым, так как похоже, что вы хотите получить среднее значение для "a" и "b". Кроме того, вы можете обобщить его, передав также функцию.