You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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")

原因与修正方案

核心问题

  1. ggarrange依赖包缺失:代码中使用了ggarrange函数,但未加载其所属的ggpubr包,可能导致绘图上下文异常,干扰后续表格输出。
  2. tableGrob输出方式错误:tableGrob生成的是grid图形对象,直接用print()无法在ggplot的PDF设备中正确渲染,需要用grid.draw()输出。
  3. 表格尺寸适配问题:默认的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:56:00