【问题标题】:How to make "persistent" plots with ggplot for ggarrange before and after data manipulation in R如何在 R 中的数据操作之前和之后使用 ggplot 为 ggarrange 制作“持久”图
【发布时间】:2020-08-22 13:10:38
【问题描述】:

我正在尝试通过 for 循环为我的数据集中的多个列创建数据操作前后的数据比较图。最终,我想将所有比较图保存到一个 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 创建“仅”一个链接到数据的图形对象有关,所以当我再次打印它时,它会再次访问数据并获取操作数据而不是获取以前的“快照” . 将图表保存到单独的列表也无济于事,它们也“链接”到被操纵的数据。

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

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

【问题讨论】:

  • 您是否尝试在 for 循环的末尾添加 dev.off()?
  • 是的,我尝试使用 dev.off(),也在每次 print() 之后。它没有帮助。

标签: r object ggplot2 persistent


【解决方案1】:

拼凑包有帮助。一种选择是创建一个绘图列表列表,然后将列表展平,并使用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?

【讨论】:

  • 我不明白,pre和post不完全一样吗?显然,x 轴会有所不同。
  • 确实如此。我会调查的。
  • @RuiBarradas 和 Elena,请参阅更新。我猜是一些内部引用问题
  • 是的,确实如此,但我的输入数据约为 1GB,因此我尽量避免不必要地扩大工作空间。当然,另一种选择是简单地使用“post”数据创建新列,但我想知道是否有办法解决它,所以是否可以在相同数据流中工作,而不是创建重复的数据框或列:-(
  • @Elena 查看更新 - 直接在 ggplot 中进行数据转换
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 2012-07-22
  • 2011-06-21
相关资源
最近更新 更多