如何通过管道转发 ggplot 对象?

jan*_*nyi 6 r pipe ggplot2

我想使用在带有magrittr管道的 ggplot 对象上定义的自定义函数。但是,我无法将 ggplot 对象通过管道传输到此函数中。

这是一个简单的例子:

library(ggplot2)
library(magrittr)

my_plot_function <- function(plot) {
    plot + geom_hline(yintercept = 3, linetype = 'dashed')
}

data(mtcars)
p <- mtcars %>%
    ggplot() +
    geom_point(aes(mpg, wt))
my_plot_function(p)
Run Code Online (Sandbox Code Playgroud)

如果我可以my_plot_function()在链中使用如下,那就太好了:

mtcars %>%
    ggplot() +
    geom_point(aes(mpg, wt)) %>%
    my_plot_function()
Run Code Online (Sandbox Code Playgroud)

但是,它给出了一个错误,因为只有图层被传递到my_plot_function()而不是绘图本身。我怎么能用管道传递情节?

Moo*_*per 7

对于一个参数函数,例如您建议的函数,您可以通过定义使用以下技巧-.gg

`-.gg` <- function(e1, e2) e2(e1)

my_plot_function <- function(plot) {
  plot + geom_hline(yintercept = 3, linetype = 'dashed')
}

mtcars %>%
  ggplot() +
  geom_point(aes(mpg, wt)) -
  my_plot_function
Run Code Online (Sandbox Code Playgroud)

绘制图表


我经常使用这个技巧ggplotly

library(plotly)
mtcars %>%
  ggplot() +
  geom_point(aes(mpg, wt)) -
  ggplotly
Run Code Online (Sandbox Code Playgroud)

绘制交互式图表


或绘制中间图表

mtcars %>%
  ggplot() +
  geom_point(aes(mpg, wt)) -
  plot +
  facet_wrap(~cyl)
Run Code Online (Sandbox Code Playgroud)

绘制2个图表


对于多参数函数,您可以使用purrr::partial

my_plot_function2 <- function(plot, msg) {
  print(msg)
  plot + geom_hline(yintercept = 3, linetype = 'dashed')
}

library(purrr)
mtcars %>%
  ggplot() +
  geom_point(aes(mpg, wt)) -
  partial(my_plot_function2, msg="hello")
# [1] "hello"
Run Code Online (Sandbox Code Playgroud)

...并绘制图表


动态定义一个函数,在本例中用于编辑绘图的数据:

mtcars %>%
  ggplot() +
  geom_point(aes(mpg, wt)) -
  as_mapper(~{.$data <- head(.$data);.})
Run Code Online (Sandbox Code Playgroud)

绘制有 6 个点的图表


Dat*_*neR 6

您可以尝试定义一个不需要绘图对象的函数,然后像往常一样在ggplot.

my_plot_function <- function() {
    geom_hline(yintercept = 3, linetype = 'dashed')
}


mtcars %>%
    ggplot() +
    geom_point(aes(mpg, wt)) + my_plot_function()
Run Code Online (Sandbox Code Playgroud)

  • 您甚至可以通过返回 geom 或其他 ggplot 函数列表来从 my_plot() 获得多个 geom。 (2认同)