Контекст
Чтение виньетки Программирование с помощью dplyr Я пытался использовать операторы ...
и !!!
для реализации функции, которая обернута вокруг функций ggplot и примет произвольныйколичество аргументов, которые будут определять, какие переменные в кадре данных должны отображаться в каждой эстетике.
Моя цель
Я хотел определить функцию plot_points2()
так, чтобы
plot_points2(df, x = x, y = y, color = z)
было бы эквивалентно df %>% ggplot( mapping = aes(x = x, y = y, color = z) ) + geom_point(alpha = 0.1)
plot_points2(df, x = x, y = z, color = y)
будет эквивалентно df %>% ggplot( mapping = aes(x = x, y = z, color = y) ) + geom_point(alpha = 0.1)
plot_points2(df, x = x, y = z)
будет эквивалентно df %>% ggplot( mapping = aes(x = x, y = z) ) + geom_point(alpha = 0.1)
Что не удалось
пакетов
require(tidyverse)
require(rlang)
уменьшенный пример набора данных
df <- tibble(g1= sample(x = c(1,2,3), replace = T, size = 10000),
g2= sample(x = c("a","b","c"), replace = T, size = 10000),
x = rnorm(10000, 50, 10),
y = rnorm(10000, 0, 20) + x*2,
z = rnorm(10000, 10, 5))
df
моя попытка
plot_points2 <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(!!!args)) + geom_point(alpha = 0.1)
}
plot_points2(df, x = x, y = y, color = z)
ошибка
Error: Can't use `!!!` at top level
Call `rlang::last_error()` to see a backtrace
Почему я думаю, что это должно работать
Iпонять, что я хотел сделать, не сильно отличается от примера в виньетка , который использует эти операторы для создания функции, которая обтекает mutate()
и передает несколько аргументов, которые определяют переменные группировки (на самом делеЯ смог реализовать функцию, которая делает это с примером набора данных выше, который я публикую в качестве примера), но каким-то образом последний работает, а первый нет:
это работает
add_dif_to_group_mean <- function(df, ...) {
groups <- quos(...)
df %>% group_by(!!!groups) %>% mutate(x_dif = x-mean(x),
y_dif = y-mean(y),
z_dif = z-mean(z))
}
df %>% add_dif_to_group_mean(g1)
df %>% add_dif_to_group_mean(g1, g2)
это не
plot_points2 <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(!!!args)) + geom_point(alpha = 0.1)
}
plot_points2(df, x = x, y = y, color = z)
Я также читал, что проблема может быть связана с aes()
оценкойd только при печати графика, но в этом случае я думаю, что использование !!
и при ручной распаковке должно вызывать ту же ошибку, но это не :
plot_points2b <- function(d, ...){
args <- quos(...)
print(args)
ggplot(data = d, mapping = aes(x = !!args[[1]],
y = !!args[[2]],
color = !!args[[3]])) +
geom_point(alpha = 0.1)
}
plot_points2b(df, x = x, y = y, color = z)
На самом деле этоПоследний пример работает нормально, если вы строите 3 переменные, но не позволяет отображать число переменных, отличных от 3
, например: plot_points2b(df, x = x, y = z)
не эквивалентно
df %>% ggplot( mapping = aes(x = x, y = z) ) + geom_point(alpha = 0.1)
Вместо этого возникает ошибка:
Error in args[[3]] : subscript out of bounds
Кто-нибудь знает, какую концепцию я здесь упускаю?Заранее спасибо!