Я пытаюсь заставить ggplot2 принимать списки и делать элементы списков доступными для других пользовательских функций geom.
У меня есть новая функция ggplot, которая принимает списки:
ggplot.list <- function(data = NULL,
mapping = ggplot2::aes(),
...,
environment = parent.frame()) {
p <- ggplot2::ggplot(data=data[[1]],mapping=mapping,..., environment=environment)
p$data_ext <- data[[2]]
p
}
Я создаю свой список и рисую первый data.frame:
l <- list(tibble(x=1:10, y=1:10), tibble(x=1:10+100, y =1:10+200))
ggplot(l) + geom_point(aes(x=x,y=y))
В идеале я хотел бы создать что-то вроде этого (что не работает), другой geom, который по умолчанию берет data_ext
из объекта ggplot
geom_point2 <- function (mapping = NULL, data_ext = NULL, stat = "identity", position = "identity",
..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
layer(data_ext = data_ext, mapping = mapping, stat = stat, geom = GeomPoint,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...))
}
ggplot(l) + geom_point(aes(x=x,y=y)) + geom_point2(aes(x=x,y=y))
Я вижу, что мой второй data.frame находится внутри объекта ggplot, но я не знаю, как получить к нему доступ; то есть ggplot(l)$data_ext
работает. Я пробовал играть с ggproto, но у меня недостаточно опыта, чтобы понять, что с ним делать и может ли это помочь.
ДОБАВЛЕНО. Между прочим, я могу добиться того, чего хочу, с помощью канала, но я не хочу запутывать потенциальных пользователей моих функций:
pipe_point2 <-function (plot, mapping = NULL, data = NULL, stat = "identity", position = "identity",
..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE)
{
plot + layer(data = plot$data_ext, mapping = mapping, stat = stat, geom = GeomPoint,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...))
}
{ggplot(l) + geom_point(aes(x=x,y=y))} %>% pipe_point2(aes(x=x,y=y))