【问题标题】:Store multiple plots into a list using a function使用函数将多个图存储到列表中
【发布时间】:2020-01-29 04:32:43
【问题描述】:

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

我正在尝试使用previous thread 中建议的列表函数,但是我很难创建自己的函数来满足我的需要。

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

heatlist.germ <- split(heatlist.germ, f=as.factor(heatlist.germ$plot))

之后,我尝试创建一个列表函数,以后可以使用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)

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

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

任何帮助将不胜感激。

【问题讨论】:

  • plots &lt;- lapply(heatlist.germ, plot_data_fcn),并从你的函数内部删除[[i]]

标签: r ggplot2


【解决方案1】:

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

第一个问题是你不应该在你的函数中使用你的[[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"

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

如果你想在第 n 帧中包含一个指示它是哪个元素的索引,我认为这是将数据“压缩”在一起,所以我建议Map。 (也可以使用purrr::imap或相关的tidyverse函数。)

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"

要了解Maplapply 的关系,然后了解lapply(datalist, myfunc) 已“展开”为类似以下内容:

myfunc(datalist[[1]])
myfunc(datalist[[2]])
myfunc(datalist[[3]])

但是,对于Map,它需要一个函数,该函数必须在每次调用中接受一个或多个参数。这样,Map 接受与函数接受参数一样多的列表(或向量)。这两个函数是同义词

lapply(datalist, myfunc) # data first,     function second
Map(myfunc, datalist)    # function first, data second

一个更复杂的调用如下展开:

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]])

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

【讨论】:

  • 非常感谢!!这是对每个功能的幕后花絮的非常透彻的解释。我更欣赏这个答案,因为它扩展了我对代码本身的理解。谢谢!
猜你喜欢
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
相关资源
最近更新 更多