【问题标题】:How to `dput` a `ggplot` object?如何`dput`一个`ggplot`对象?
【发布时间】:2018-11-15 06:53:53
【问题描述】:

我正在寻找一种方法来保存一些ggplot 对象以供以后使用。 dput 函数创建一个字符串,当传递给dget() 时会返回意外< 的错误:

  • 第一个在这里:.internal.selfref = <。这可以通过将.internal.selfref 设置为NULL 轻松解决。
  • 剩余的七个分布在不同的属性中,参数为<environment>。我尝试将<environment> 更改为NULLenvironment() 之类的东西,但它们都不起作用 - 环境设置不正确并且返回了找不到对象错误。

一些搜索让我找到了函数ggedit::dput.ggedit。但它给了我错误:

# Error in sprintf("%s = %s", item, y) : 
#   invalid type of argument[2]: 'symbol'

我在想,要么我使用dput 函数正确设置环境,要么我弄清楚为什么ggedit::dput.ggedit 不起作用...

有什么想法吗?

【问题讨论】:

  • 您可以将其保存为.rdssaveRDS()
  • 请注意,我宁愿保存 ggplot 的输入数据(不是 ggplot 对象)。然后,如果 ggplot 库升级/降级,您保存的对象可能无法打印,或者您获得了新的数据输入来绘制,那么最好让数据和脚本重新运行。
  • 您能否在有关“为什么”要使用 dput 保存 ggplot 对象的问题中添加一些信息?要从数据到最终的可视化图表(假设您已将 ggplot2 对象分配给名为 gg 的变量),它会执行 ggplot_gtable(ggplot_build(gg))。您应该查看每个人的str(),尤其是最初的gg。这——rud.is/books/creating-ggplot2-extensions/…——为你展示了它们。可能导致 RDS 巨大尺寸的 1 件事是原始 gg 的 1 个元素是 $ plot_env :<environment: R_GlobalEnv> (因此顺带一提。
  • 各种对象结构(甚至gg)随着每个ggplot2版本而变化,因此@zx8754指出随着时间的推移依赖该结构的序列化版本是“不安全的”。如果您真的想将其“序列化”到一个文件中,dput() 您的最终数据并将 + ggplot2 绘图命令放入 R 文件中。
  • 所以,然后将您传递到 ggplot2 绘图构建链中的对象的每个汇总版本保存为 RDS,并在调用 ggplot() 之前将其读入。这是很常见的事情。我从 Athena 和 Drill 中提取 lots(我的意思是,你无缘无故地使用粗体,所以我认为这是流行的)数据,并做同样的事情,效果非常好。我认为您没有意识到 ggplot2 携带数据(我必须指出这一点,因为您没有费心阅读我发布的链接)。

标签: r ggplot2


【解决方案1】:

不使用dput(),但要保存您的ggplot对象以供以后使用,您可以将它们保存为.rds文件(就像任何R对象一样)。

例子:

my_plot <- ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy))

saveRDS(my_plot, "my_plot.rds")

并在另一个会话、另一个脚本等中恢复您的对象。

my_plot <- readRDS("my_plot.rds")

【讨论】:

  • 谢谢你的回答,但是......当我dput 我的ggplot 它只是以45kb 的文件大小立即完成,但是当我saveRDS 相同ggplot 它文件大小为 1.8Gb 需要几分钟!怎么了...?我有成千上万的地块,这肯定不能胜任……
  • 也许按照他们的建议尝试用全局环境替换绘图环境? 1.8Gb 看起来确实很大……
  • 我不知道您的工作流程是什么样的,但也许另一种选择可能是不保存绘图并在以后需要时获取生成绘图的脚本?
  • 需要一些时间来弄清楚...也许您的最后一条评论是目前最好的解决方法。但我有兴趣了解更多。
【解决方案2】:

你可以试试tidyverse

使用nestmap 将图表保存在小标题中的数据旁边。

library(tidyverse)

res <- mtcars %>% 
  as.tibble() %>%   
  nest() %>%  
  mutate(res=map(data, ~ggplot(.,aes(mpg, disp)) + geom_point()))

然后使用savesaveRDS 保存data.frame。 最后,调用剧情:

res$res

tibble(mtcars) 的大小为 4kb,而情节则为 21kb。

【讨论】:

  • as_tibble()(所有tidyverse函数都使用snake case)
  • 我不在乎。 as.tibbleas_tibble 相同;两者都调用相同的方法。使用任何你想要的。
猜你喜欢
  • 2021-11-23
  • 2015-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-04
  • 2021-10-23
  • 2019-08-24
  • 1970-01-01
相关资源
最近更新 更多