如何在 R 中的数据操作前后使用 ggplot 为 ggarrange 绘制 "persistent" 图

How to make "persistent" plots with ggplot for ggarrange before and after data manipulation in R

我正在尝试通过 for 循环为数据集中的多个列创建数据比较图 before-after 数据操作。最后,我想将所有比较图保存到一个 pdf 文件中。首先,我之前生成绘图,操作数据,之后生成绘图,并希望通过 ggarrange 将它们并排放置(我也尝试了来自 gridExtra 的 grid.arrange,但这并没有解决问题)。 然而,我得到的是数据处理后的相同图(尽管标题不同)。

这是一个可重现的例子:

library(rlist)
library(ggplot2)
library(ggpubr)
head(iris)
plot_before <-  list()
plot_after <- list()
plots <- list()

for (i in 1:4){
  p <-  ggplot(iris,aes(iris[,i])) + geom_histogram()+ggtitle(paste0(i,"_pre"))
  print(p)
  plot_before <- list.append(plot_before,p)
  #do something with your data
  iris[,i] <- 3*iris[,i]
  p2 <-  ggplot(iris,aes(iris[,i])) + geom_histogram()+ggtitle(paste0(i,"_post"))
  print(p2)
  plot_after <- list.append(plot_after, p2)
  q <-  ggarrange(p,p2)  #here, p is already linked to modified data
  print(q)
  plots <- list.append(plots, q)
}
#try to access plots from lists
for (i in 1:4){
  print(plot_before[[i]])
  print(plot_after[[i]])
  print(plots[[i]])
}

我想这与 ggplot 创建 "only" 一个图形 object 链接到数据有关,所以当我再次打印它时,它再次访问数据并获取操作数据而不是获取之前的 "snapshot"。 将图表保存到单独的列表也无济于事,它们也是 "linked" 操纵数据。

有没有办法制作持久的 ggplot object 而不是将其链接到数据?

当然可以使用修改后的数据创建新列并引用这些列或创建一个全新的数据框,但我想避免数据重复。

拼凑包有帮助。一个选项是创建一个地块列表列表,然后展平列表,并使用 patchwork::wrap_plots.

一个更ggplot的方法是避免在aes中使用向量。我已经包含了创建 aes 的方式。

更新

根据您的评论 - 您不想对数据进行两次修改,也不想保存额外的列。现在循环既修改了数据又创建了所需绘图的列表。

library(tidyverse)
library(patchwork)

p_list <- list()
sel_col <- names(iris)[1:4]

for(i in sel_col){
  p <-  ggplot(iris, aes(!!sym(i))) +
    geom_histogram()+
    ggtitle(paste0(i,"_pre"))

  p_list[[i]][["pre"]] <- p

  iris[i] <- 3*iris[,i ]

  p2 <- ggplot(iris, aes(!!sym(i))) + 
    geom_histogram()+
    ggtitle(paste0(i,"_post"))

  p_list[[i]][["post"]] <- p2
}

head(iris) # iris has changed
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1         15.3        10.5          4.2         0.6  setosa
#> 2         14.7         9.0          4.2         0.6  setosa
#> 3         14.1         9.6          3.9         0.6  setosa
#> 4         13.8         9.3          4.5         0.6  setosa
#> 5         15.0        10.8          4.2         0.6  setosa
#> 6         16.2        11.7          5.1         1.2  setosa

ls_unnest <- do.call(list, unlist(p_list, recursive=FALSE))

wrap_plots(ls_unnest, ncol = 2)

reprex package (v0.3.0)

于 2020-05-07 创建

有用的帖子:How to flatten a list of lists?