如何在R函数中包含一个绘图作为可能的输出?

d5vmydt9  于 2023-05-11  发布在  其他
关注(0)|答案(2)|浏览(107)

验证码:

example <- function(x, y){
  Plot <- plot(x, y)
  return(list(Plot = Plot, Mean = c(mean(x), mean(y))))
}

set.seed(1)
x <- rnorm(10)
set.seed(2)
y <- rnorm(10)
example(x, y)

每次我们调用函数example(x, y)时,图就会出来。当我调用函数example(x, y)时,我怎么可能不打印图,但在需要时可以通过example(x, y)$Plot获取图?
谢谢!

xqnpmsa8

xqnpmsa81#

一个更复杂的解决方案是使用S3分派,这样当您查看整个输出时,您只能看到plot调用,但当您查看plot对象时,您会得到绘制的实际图。这需要你的main函数和两个print方法:

example <- function(x, y, ...) {
  
  plot_call <- substitute(
    plot(x = x, y = y, ...)
    )
  
  args <- as.list(plot_call)[-1]
  args$x <- x
  args$y <- y
  if(! "xlab" %in% names(args)) args$xlab <- deparse(substitute(x))
  if(! "ylab" %in% names(args)) args$ylab <- deparse(substitute(y))
  recording <- as.call(c(quote(plot), args))

  Plot <- structure(list(plot_call = plot_call, 
                         recording = recording),
                    class = "Plot")
  
  structure(list(Plot = Plot, 
                 Mean = c(mean(x), mean(y))),
            class = "myclass")
}

print.Plot <- function(obj, ...) {
  eval(obj$recording)
  invisible(obj)
}

print.myclass <- function(obj, ...) {
  print(list(Plot = obj$Plot$plot_call,
             Mean = obj$Mean))
  invisible(obj)
}

这会产生以下行为:

example(x, y)
#> $Plot
#> plot(x = x, y = y)
#> 
#> $Mean
#> [1] 0.1322028 0.2111516

但是

example(x, y)$Plot

my_obj <- example(mtcars$wt, mtcars$mpg, col = "red")

my_obj
#> $Plot
#> plot(x = mtcars$wt, y = mtcars$mpg, col = "red")
#> 
#> $Mean
#> [1]  3.21725 20.09062

但是

my_obj$Plot

创建于2023-05-08使用reprex v2.0.2

编辑

看起来OP正在寻找一个使用cowplot输出多个绘图页面的函数,但用户可以选择访问单个绘图。这可以更容易地完成,这次使用单个print方法:

library(ggplot2)

example <- function(x, y) {

  df <- data.frame(x, y)

  plot1 <- ggplot(df, aes(x, y)) + geom_point()
  plot2 <- ggplot(df, aes(x)) + geom_density()
  plot3 <- ggplot(df, aes(y)) + geom_density()
  plot4 <- ggplot(df, aes(sort(x), sort(y))) + geom_point() + geom_abline()

  structure(list(plot1, plot2, plot3, plot4), class = "multiplot")
}

print.multiplot <- function(x, ...) {
  print(cowplot::plot_grid(x[[1]], x[[2]], x[[3]], x[[4]]))
}

这允许:

example(x, y)

但也允许访问单独的图:

example(x, y)[[1]]

s4n0splo

s4n0splo2#

一种简单的方法是添加一个参数,让用户决定是否要在输出中包含绘图。

example <- function(x, y, incl_plot = T) {
  
  Mean = c(mean(x), mean(y))

  if(incl_plot) {
    Plot = plot(x,y)
    list(Plot = Plot, Mean = Mean)
  } else {
    Mean
  }
}

example(x,y, incl_plot = F) # only the Mean is returned
example(x,y) # both objects are returned

相关问题