为何table grob无法在PDF输出文件中显示?
问题
尝试将一系列绘图与tableGrob输出到单个PDF文件中,代码执行无报错,但表格未出现在输出PDF里。代码如下:
library(boot) library(ggplot2) library(ggblanket) library(gridExtra) library(tidyverse) # 定义函数返回bootstrap样本的均值和标准差 fun_mean <- function(data,i){ d <- data[i] return(mean(d, na.rm=TRUE)) } fun_sd <- function(data,i){ d <- data[i] return(sd(d, na.rm=TRUE)) } # 加载各设备数据 mydata <- data.frame( Device1 = c(6.3, 8.3, 6.6, 0, 8.4, 8.6), Device2 = c(8.2, 8.7, 8.6, 7.9, 7.1, 7.6), Device3 = c(7.1, 6.4, 6.6, 8, 7.5, 10.3), Device4 = c(8, 7.7, 7.3, 0, 9.4, 6.4), Device5 = c(8.5, 6.8, 0, 0, 7.3, 9.7), Device6 = c(5.9, 7.5, 6.5, 0, 9.8, 7.8), Device7 = c(7.6, 5.3, 6.7, 0, 6.6, 7.4), Device8 = c(9.5, 5.6, 8.8, 0, 8.6, 8.3), Device9 = c(8.5, 7.4, 0, 0, 9.2, 8.6), Device10 = c(7.8, 6.9, 8.6, 6.7, 6.8, 6.1) ) # 将所有0值替换为NA mydata[mydata == 0] <- NA # 设置bootstrap样本数量 R<- 10000 # 创建存储结果的数据框 results_df <- data.frame( Device = colnames(mydata), Parameter = rep(c("Mean", "S.Dev"), each = ncol(mydata)), Num.Resamples = rep(R, 2 * ncol(mydata)) ) # 初始化存储各设备结果的空列表 device_results <- list() # 创建PDF文件输出结果/绘图 pdf("Bootstrap Results.pdf") # 估算bootstrap参数并导出结果 for (i in 1:ncol(mydata)) { # 向控制台打印状态 cat(paste("Device", i, "\n")) # 估算bootstrap参数 bo_mean <- boot(data = mydata[, i], statistic = fun_mean, R = R) bo_sd <- boot(data = mydata[, i], statistic = fun_sd, R = R) # 获取参数估计的置信区间 ci_mean <- boot.ci(bo_mean, conf = 0.95, type = "bca") ci_sd <- boot.ci(bo_sd, conf = 0.95, type = "bca") # 存储置信区间边界 ci_mean_bounds <- ci_mean$bca[c(4, 5)] ci_sd_bounds <- ci_sd$bca[c(4, 5)] # 创建重采样的直方图 df_mean <- data.frame(samples = bo_mean$t) plot_hist <- gg_histogram( data = df_mean, x = samples ) # 创建重采样的QQ图 plot_qq <- gg_qq( data = df_mean, sample = samples ) + geom_qq_line(color = "blue") # 组合绘图 plot_combo <- ggarrange(plot_hist, plot_qq, ncol = 2, nrow = 1, widths = c(600, 600), heights = 300) # 将组合绘图打印到PDF文件 print(plot_combo) # 存储当前设备的结果 device_results[[i]] <- data.frame( Device = colnames(mydata)[i], `Num.Resamples` = R, `Mean` = paste(format(bo_mean$t0, nsmall = 5), " (", format(ci_mean_bounds[1], nsmall = 5), ",", format(ci_mean_bounds[2], nsmall = 5), ")"), `S.Dev` = paste(format(bo_sd$t0, nsmall = 5), " (", format(ci_sd_bounds[1], nsmall = 5), ",", format(ci_sd_bounds[2], nsmall = 5), ")") ) cat("\n") } # 将所有设备的结果合并到单个数据框 results_df <- bind_rows(device_results) # 将结果表格打印到PDF文件 # 这部分似乎无法正常工作 results_grob <- tableGrob(results_df) print(results_grob) # 关闭PDF设备 dev.off() # 将合并后的表格打印到文本文件 write.table(results_df, "Bootstrap Results.txt", row.names = FALSE, quote = FALSE, sep = "\t")
原因与修正方案
核心问题
ggarrange依赖包缺失:代码中使用了ggarrange函数,但未加载其所属的ggpubr包,可能导致绘图上下文异常,干扰后续表格输出。tableGrob输出方式错误:tableGrob生成的是grid图形对象,直接用print()无法在ggplot的PDF设备中正确渲染,需要用grid.draw()输出。- 表格尺寸适配问题:默认的
tableGrob尺寸可能超出PDF页面范围,导致表格被裁剪或完全隐藏。
修正步骤
- 加载
ggpubr包,确保ggarrange正常运行; - 使用
grid::grid.draw()替代print()输出表格对象; - 调整PDF页面尺寸和表格字体大小,避免表格被裁剪。
修正后的完整代码
library(boot) library(ggplot2) library(ggblanket) library(gridExtra) library(grid) # 加载grid包用于grid.draw library(ggpubr) # 加载ggpubr包用于ggarrange library(tidyverse) # 定义函数返回bootstrap样本的均值和标准差 fun_mean <- function(data,i){ d <- data[i] return(mean(d, na.rm=TRUE)) } fun_sd <- function(data,i){ d <- data[i] return(sd(d, na.rm=TRUE)) } # 加载各设备数据 mydata <- data.frame( Device1 = c(6.3, 8.3, 6.6, 0, 8.4, 8.6), Device2 = c(8.2, 8.7, 8.6, 7.9, 7.1, 7.6), Device3 = c(7.1, 6.4, 6.6, 8, 7.5, 10.3), Device4 = c(8, 7.7, 7.3, 0, 9.4, 6.4), Device5 = c(8.5, 6.8, 0, 0, 7.3, 9.7), Device6 = c(5.9, 7.5, 6.5, 0, 9.8, 7.8), Device7 = c(7.6, 5.3, 6.7, 0, 6.6, 7.4), Device8 = c(9.5, 5.6, 8.8, 0, 8.6, 8.3), Device9 = c(8.5, 7.4, 0, 0, 9.2, 8.6), Device10 = c(7.8, 6.9, 8.6, 6.7, 6.8, 6.1) ) # 将所有0值替换为NA mydata[mydata == 0] <- NA # 设置bootstrap样本数量 R<- 10000 # 创建存储结果的数据框 results_df <- data.frame( Device = colnames(mydata), Parameter = rep(c("Mean", "S.Dev"), each = ncol(mydata)), Num.Resamples = rep(R, 2 * ncol(mydata)) ) # 初始化存储各设备结果的空列表 device_results <- list() # 创建PDF文件,设置合适的页面尺寸避免表格被裁剪 pdf("Bootstrap Results.pdf", width = 12, height = 8) # 估算bootstrap参数并导出结果 for (i in 1:ncol(mydata)) { # 向控制台打印状态 cat(paste("Device", i, "\n")) # 估算bootstrap参数 bo_mean <- boot(data = mydata[, i], statistic = fun_mean, R = R) bo_sd <- boot(data = mydata[, i], statistic = fun_sd, R = R) # 获取参数估计的置信区间 ci_mean <- boot.ci(bo_mean, conf = 0.95, type = "bca") ci_sd <- boot.ci(bo_sd, conf = 0.95, type = "bca") # 存储置信区间边界 ci_mean_bounds <- ci_mean$bca[c(4, 5)] ci_sd_bounds <- ci_sd$bca[c(4, 5)] # 创建重采样的直方图 df_mean <- data.frame(samples = bo_mean$t) plot_hist <- gg_histogram( data = df_mean, x = samples ) # 创建重采样的QQ图 plot_qq <- gg_qq( data = df_mean, sample = samples ) + geom_qq_line(color = "blue") # 组合绘图 plot_combo <- ggarrange(plot_hist, plot_qq, ncol = 2, nrow = 1) # 将组合绘图打印到PDF文件 print(plot_combo) # 存储当前设备的结果 device_results[[i]] <- data.frame( Device = colnames(mydata)[i], `Num.Resamples` = R, `Mean` = paste(format(bo_mean$t0, nsmall = 5), " (", format(ci_mean_bounds[1], nsmall = 5), ",", format(ci_mean_bounds[2], nsmall = 5), ")"), `S.Dev` = paste(format(bo_sd$t0, nsmall = 5), " (", format(ci_sd_bounds[1], nsmall = 5), ",", format(ci_sd_bounds[2], nsmall = 5), ")") ) cat("\n") } # 将所有设备的结果合并到单个数据框 results_df <- bind_rows(device_results) # 生成表格对象并调整字体大小,去掉默认行号 results_grob <- tableGrob(results_df, theme = ttheme_minimal(base_size = 10), rows = NULL) # 使用grid.draw输出表格到PDF grid.draw(results_grob) # 关闭PDF设备 dev.off() # 将合并后的表格打印到文本文件 write.table(results_df, "Bootstrap Results.txt", row.names = FALSE, quote = FALSE, sep = "\t")
内容的提问来源于stack exchange,提问作者CBRF23
相关产品推荐
相关产品推荐

