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

使用gtsummary导出docx时tab_stub_indent缩进丢失问题求助

解决gt导出docx时缩进丢失的问题

问题原因

gt::tab_stub_indent是基于HTML/CSS的样式实现,导出docx时,pandoc的格式转换不支持这类样式,导致缩进效果丢失。

解决方案1:修改标签文本添加前置空格(最简单高效)

直接在ENV_开头的变量标签前添加非断空格(避免被自动合并),替代gt的缩进功能,导出docx和Excel时都会保留空格实现缩进效果。

修改后的完整代码:

library(tidyverse)
library(gtsummary)
library(gt)

filtered_database = data.frame(
  INDIV_AGE = rnorm(100, mean = 50, sd = 4),
  INDIV_GENDER = rbinom(100, size=1, prob = 0.6),
  INDIV_ETHNICS = sample(c("North America", "Western Europe", "Africa", "Eastern Europe", "Asia", "Other"), size = 100, replace = T, prob = c(0.3, 0.2, 0.4, 0.02, 0.01, 0.07)),
  INDIV_ECOGRP = sample(c(1,2,3,4), size = 100, replace = T, prob = c(0.6, 0.1, 0.2, 0.1)),
  ENV_POLLEVEL = rpois(100, lambda = 4), 
  ENV_FLOODPROFILE = sample(c("Low", "Intermediate", "High", "Extreme"), size = 100, replace = T, prob = c(0.1, 0.65, 0.2, 0.05))
)
filtered_database[] <- lapply(filtered_database, function(x) { x[sample(seq_along(x), 0.1 * length(x))] <- NA; x })

a = filtered_database |>
  tbl_summary(
    include = everything(),
    missing = "always",
    missing_text = "Missing data",
    missing_stat = "{N_miss} ({p_miss}%)",
    type = INDIV_AGE ~ "continuous",
    statistic = list(
      all_continuous() ~ "{median} [{p25}-{p75}]",
      all_categorical() ~ "{n} ({p}%)"
      ),
    by = INDIV_GENDER
  ) |>
  modify_header(
    label = "",
    stat_2 = "**Yes**\nN={n}",
    stat_1 = "**No**\nN={n}") |>
  modify_spanning_header(all_stat_cols()~"**Gender**") |>
  add_p() |>
  bold_p() |>
  modify_column_alignment(columns = c("stat_1", "stat_2"), align = "right") |>
  as_gt(rowname_col = "label") |>
  tab_header(
    title = "Description of the population") |>
  cols_align("right", columns = last_col())

gt_var_names = a$`_data`$variable

b = a |>
  # 给ENV开头的标签添加4个非断空格实现缩进
  text_replace(
    locations = cells_stub(rows = str_detect(gt_var_names, "^ENV_")),
    pattern = "^(ENV.*)",
    replacement = "\u00A0\u00A0\u00A0\u00A0\\1"
  ) |>
  tab_row_group(
    label = "Individual characteristics",
    rows = str_detect(gt_var_names, "^INDIV_")
  ) |>
  tab_row_group(
    label = "Environment characteristics",
    rows = str_detect(gt_var_names, "^ENV_")
  ) |>
  row_group_order(groups = c("Environment characteristics", "Individual characteristics")) |>
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_row_groups()
  ) |>
  tab_style(
    style = cell_text(style = "italic", color = "gray65"),
    locations = cells_body(
      columns = everything(),
      rows = row_type == "missing"
    )
  ) |>
  tab_style(
    style = cell_text(style = "italic"),
    locations = cells_stub(
      rows = row_type == "missing"
    )
  )

# 导出docx
b |> gtsave("Population.docx")

说明

  • 用\u00A0表示非断空格,避免Word/Excel自动合并空格;可根据需要调整空格数量控制缩进幅度。
  • 此方法导出HTML、docx、Excel时均能保留缩进效果。

解决方案2:用officer包实现原生Word缩进(更精准)

如果需要和Word原生段落缩进一致的效果,可将gt表格转为数据框后,用officer包手动设置单元格缩进:

library(tidyverse)
library(gtsummary)
library(gt)
library(officer)

# 生成表格的代码和之前一致,直到得到gt对象b

# 将gt表格转为数据框
gt_table_df <- b %>% as.data.frame()

# 创建docx文档
doc <- read_docx()

# 添加表格到文档
doc <- doc %>%
  body_add_table(
    value = gt_table_df,
    style = "Table Grid"  # 使用Word内置表格样式
  )

# 找到ENV开头的行索引
env_row_indices <- which(grepl("^ENV", gt_table_df$label))

# 为目标行的第一列设置缩进(10磅,可调整)
for (row_idx in env_row_indices) {
  doc <- doc %>%
    body_set_paragraph_properties(
      location = cell_location(
        row = row_idx + 1,  # 表格标题占1行,所以行号+1
        col = 1,
        part = "body"
      ),
      fp_par(text.indent = 10)
    )
}

# 保存文档
print(doc, target = "Population_with_indent.docx")

说明

  • 需要提前熟悉officer包的表格操作逻辑,适合对格式要求极高的场景。

内容的提问来源于stack exchange,提问作者Sigil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:27:03