如何在officedown生成的docx中实现真实Figure/Table类型交叉引用
使用{officedown}生成.docx格式报告时,若不想采用官方文档第4.6、4.7节推荐的"bookmark"类型交叉引用表格和图片,需要生成的docx中引用类型为原生的"Figure"和"Table"类型。
根据已知的技术方案,实现该功能需要用到{SEQ Figure \* arabic}和{SEQ Table \* arabic}两类Word域,现有officer::slip_in_seqfield()、crosstable::body_add_table_legend()等实现方案仅适配{officer}语法,不适用于{officedown}语法。
- {officer}语法:以
read_docx() %>%开头、采用dplyr链式调用的R脚本写法,可参考官方对应示例 - {officedown}语法:在Rmd脚本代码块中使用
block_caption()和run_autonum()的写法,可参考官方对应示例
是否可以修改officedown的默认实现方案,得到可在文本中交叉引用的真实"Figure"和"Table"类型引用?
你也可以使用{officer}包的
run_autonum()和block_caption()函数。以下是对表格@ref(tab:tabmtcars2)和图片@ref(fig:figmtcars2)的交叉引用示例,该方法可用于表格和图片,但生成的MS Word中对应引用类型始终为"bookmark"。
# 表格 run_autonum(seq_id = "tab", bkm = "tabmtcars2") %>% block_caption(autonum = ., label = "mtcars table", style = "Table Caption") head(mtcars) # 图片 ggplot(head(mtcars), aes(x = mpg, y = hp)) + geom_point() + theme_bw() run_autonum(seq_id = "fig", bkm = "figmtcars2") %>% block_caption(autonum = ., label = "mtcars figure", style = "Image Caption")

不需要修改officedown包的底层源码,仅调整参数配置即可实现需求,具体操作如下:
- 调整
run_autonum的seq_id参数,直接对应Word原生的序列名:表格使用seq_id = "Table",图片使用seq_id = "Figure",保留bkm参数作为锚点即可。 - 正文交叉引用时不使用默认的
\@ref(xxx)写法,改用officer::run_seqfield()构造原生REF域指向对应书签。
修改后的代码示例如下:
library(officedown) library(officer) library(ggplot2) # 表格 run_autonum(seq_id = "Table", # 替换为Word原生表格序列名 bkm = "tabmtcars2") %>% block_caption(autonum = ., label = "mtcars表格", style = "Table Caption") head(mtcars) # 图片 ggplot(head(mtcars), aes(x = mpg, y = hp)) + geom_point() + theme_bw() run_autonum(seq_id = "Figure", # 替换为Word原生图片序列名 bkm = "figmtcars2") %>% block_caption(autonum = ., label = "mtcars图片", style = "Image Caption")
正文交叉引用时使用行内R代码即可:
- 引用表格:
`r run_seqfield(str = "REF tabmtcars2 \\h")` - 引用图片:
`r run_seqfield(str = "REF figmtcars2 \\h")`
生成的docx中,这类引用的类型会被Word识别为原生的「表格」和「图」,和手动插入的交叉引用完全一致,后续全选更新域即可同步编号变动。如果需要中文的「表」「图」前缀,直接在block_caption的label参数中添加,或调整Word模板的标题样式前缀即可,不会影响序列和引用的识别。
内容的提问来源于stack exchange,提问作者Paul Schmidt

