在R中,嵌套映射生成的绘图为何是列表而非ggplot对象?
嵌套映射生成的ggplot无法导入PowerPoint的问题解决
问题重现
通过嵌套数据集+purrr::map生成多个ggplot后,提取单个绘图时得到的是list类型,而非ggplot对象,导致无法用officer包导入PowerPoint,转换时出现报错。可复现代码如下:
library(purrr) library(dplyr) library(ggplot2) library(tidyr) # 按cyl嵌套数据 mt_nest <- mtcars %>% nest(data = !(cyl)) # 生成每个cyl对应的绘图 mt_plots <- mt_nest %>% mutate(plots = map( .x = data, ~ggplot(.x, aes(x = gear, y = mpg)) + geom_col())) # 提取cyl=6对应的绘图 one_plot_from_nest <- mt_plots$plots[mt_plots$cyl == 6] # 打印正常,但类型为list class(one_plot_from_nest) # 转换时报错 as_ggplot(one_plot_from_nest) ggplotGrob(one_plot_from_nest)
报错信息
使用as_ggplot()时:
Error in gList(...) : only 'grobs' allowed in "gList"
使用ggplotGrob()时:
Error in UseMethod("ggplot_build") : no applicable method for 'ggplot_build' applied to an object of class "list"
问题原因
mt_plots$plots本身是存储ggplot对象的列表,使用[索引(如mt_plots$plots[mt_plots$cyl == 6])会返回长度为1的子列表,而非单个ggplot对象。而直接过滤数据生成的one_plot是单个ggplot实例,因此类型符合要求。
解决方法
1. 正确提取单个ggplot对象
改用双括号[[索引,直接从列表中取出单个ggplot对象:
# 方法1:用which定位位置后用[[提取 one_plot_from_nest <- mt_plots$plots[[which(mt_plots$cyl == 6)]] # 方法2:结合dplyr过滤后提取 one_plot_from_nest <- mt_plots %>% filter(cyl == 6) %>% pull(plots) %>% .[[1]] # 验证类型 class(one_plot_from_nest) # 返回"gg" "ggplot"
2. 批量导入PowerPoint(无需单独提取)
如果需要将所有生成的绘图批量导入PPT,直接遍历plots列表即可,无需逐个转换:
library(officer) # 创建空白PPT ppt <- read_pptx() # 遍历每个绘图,添加到新幻灯片 walk(mt_plots$plots, function(plot) { ppt <- ppt %>% add_slide(layout = "Title and Content", master = "Office Theme") %>% ph_with(value = plot, location = ph_location_type(type = "body")) }) # 保存PPT print(ppt, target = "mtcars_plots.pptx")
内容的提问来源于stack exchange,提问作者J.Sabree
相关产品推荐
相关产品推荐

