使用函数将多个绘图存储到列表中

Cam*_* So 2 r ggplot2

我正在尝试将 生成的多个图存储ggplot2到一个列表中。

我正在尝试使用上一个线程中建议的列表函数,但是我很难创建自己的函数来满足我的需求。

首先,我使用以下代码将基于因子的数据帧拆分为列表:

heatlist.germ <- split(heatlist.germ, f=as.factor(heatlist.germ$plot))
Run Code Online (Sandbox Code Playgroud)

之后,我尝试创建一个稍后可以使用的列表函数lapply

plot_data_fcn <- function (heatlist.germ) {
  ggplot(heatlist.germ[[i]], aes(x=posX, y=posY, fill=germ_bin)) + 
    geom_tile(aes(fill=germ_bin)) + 
    geom_text(aes(label=germ_bin)) +
    scale_fill_gradient(low = "gray90", high="darkolivegreen4") +
    ggtitle(plot) +
    scale_x_continuous("Position X", breaks=seq(1,30)) +
    scale_y_continuous("Position Y (REVERSED)", breaks=seq(1,20))
  }

heatlist.test <- lapply(heatlist.germ[[i]], plot_data_fcn)
Run Code Online (Sandbox Code Playgroud)

我想要完成的两件主要事情:

  1. 将 12 个 ggplots(因此 的 12 个因子plot)存储在列表中。
  2. 创建一个名为“Plot [i] Germination”的标题。

任何帮助,将不胜感激。

r2e*_*ans 5

我没有你的数据,所以我会简化绘图机制。

第一个问题是您不应该[[i]]在函数中使用引用。只需让您的函数按原样处理数据,它实际上不知道它的参数是(在另一个环境中)带有列表的元素。它只知道对象本身。

# a simple plot function
myfunc <- function(x) ggplot(x, aes_string(names(x)[1], names(x)[2])) + geom_point()
# a list of frames, nothing fancy here
datalist <- replicate(3, mtcars, simplify = FALSE)
# just call it ...
myplots <- lapply(datalist, myfunc)
class(myplots[[1]])
# [1] "gg"     "ggplot"
Run Code Online (Sandbox Code Playgroud)

myfunc被调用时,它的参数x只是 a data.frame,该函数不知道它x是帧列表中的第一(或第二或第三)帧。

如果您想包含第 n 个帧,并带有指示它是哪个元素的索引,在我看来,这是将数据“压缩”在一起,所以我建议Map. (您还可以使用purrr::imaptidyverse 或相关函数。)

myfunc2 <- function(x, title = "") ggplot(x, aes_string(names(x)[1], names(x)[2])) + geom_point() + labs(title = title)
myplots <- Map(myfunc2, datalist, sprintf("Plot number %s", seq_along(datalist)))
class(myplots[[1]])
# [1] "gg"     "ggplot"
Run Code Online (Sandbox Code Playgroud)

要了解Map与 的关系lapply,然后了解lapply(datalist, myfunc)是“展开”为以下内容:

myfunc(datalist[[1]])
myfunc(datalist[[2]])
myfunc(datalist[[3]])
Run Code Online (Sandbox Code Playgroud)

Map然而,对于,它需要一个函数,该函数在每次调用中必须接受一个或多个参数。这样,Map函数接受的参数就可以接受尽可能多的列表(或向量)。这两个函数是同义的

lapply(datalist, myfunc) # data first,     function second
Map(myfunc, datalist)    # function first, data second
Run Code Online (Sandbox Code Playgroud)

一个更复杂的调用如下所示:

titles <- sprintf("Plot number %d", seq_along(datalist)) # "Plot number 1", ...
Map(myfunc2, datalist, titles)
# equivalent to
myfunc2(datalist[[1]], titles[[1]])
myfunc2(datalist[[2]], titles[[2]])
myfunc2(datalist[[3]], titles[[3]])
Run Code Online (Sandbox Code Playgroud)

list每个参数是真(如datalist)还是向量(如)并不重要titles,只要它们的长度相同(或长度为 1)即可。