如何在父RMarkdown文档中交互式运行含子文档的上方代码块
问题描述
我有一个main Rmd文件,通过child代码块选项调用多个子Rmd文件,示例代码如下:
主文档 main.Rmd
# (main Rmd) ```{r run child 01, child="child_01.Rmd"}
<--- 在此处进行交互式操作!
**子文档 child_01.Rmd** ```r # (child 01 Rmd) ```{r } print("child 01")
**子文档 child_02.Rmd** ```r # (child 02 Rmd) ```{r } print("child 02")
编译文档可正常运行,但在`run child 02`代码块后进行交互式操作时,使用`Run all chunks above`功能无法包含子文档的代码块。需要找到无需重复罗列子文件、无需逐个打开子文档的解决办法。 # 解决方法 ## 方法一:自定义函数解析主文档并运行所有依赖代码 编写自定义R函数,自动解析主Rmd文件中当前位置上方的所有`child`代码块路径,按顺序运行子文档代码,同时执行主文档中当前位置之上的非child代码块。 1. 在主文档开头添加以下函数: ```r run_all_above_with_children <- function(current_line = rstudioapi::getSourceEditorContext()$selection[[1]]$range$start[1]) { # 获取当前主文档内容 doc_content <- rstudioapi::getSourceEditorContext()$content # 提取当前行上方的所有内容 above_content <- doc_content[1:(current_line - 1)] # 提取所有child代码块的路径 child_paths <- stringr::str_extract(above_content, '(?<=child=")[^"]+') child_paths <- child_paths[!is.na(child_paths)] # 按顺序运行每个子文档的代码 for (path in child_paths) { temp_script <- knitr::purl(path, output = tempfile(), quiet = TRUE) source(temp_script, local = globalenv()) } # 提取并运行主文档中当前行上方的非child代码块 chunk_pattern <- '(?<=```\\{r)[^}]+\\}(.*?)(?=```)' main_chunks <- stringr::str_extract_all(paste(above_content, collapse = "\n"), chunk_pattern)[[1]] main_chunks <- main_chunks[!stringr::str_detect(main_chunks, 'child=')] for (chunk in main_chunks) { eval(parse(text = chunk), envir = globalenv()) } }
- 提前安装并加载依赖包:
install.packages(c("rstudioapi", "stringr")) library(rstudioapi) library(stringr)
- 当需要运行当前位置上方所有代码(包括子文档)时,直接调用函数:
run_all_above_with_children()
方法二:利用knitr的purl批量导出并运行代码
如果主文档中子文档的调用顺序固定,可一次性将所有子文档和主文档的代码导出为单个R脚本,再运行到指定位置:
- 导出主文档及子文档的代码到统一脚本:
# 导出主文档代码 knitr::purl("main.Rmd", output = "full_script.R", quiet = TRUE) # 按主文档调用顺序追加子文档代码 cat(readLines("child_01.Rmd"), file = "full_script.R", append = TRUE) cat(readLines("child_02.Rmd"), file = "full_script.R", append = TRUE)
- 在RStudio中打开
full_script.R,找到对应主文档交互式操作位置的代码行,使用Run all lines above功能即可。
注意事项
- 方法一依赖RStudio API,仅在RStudio环境中生效;
- 若存在嵌套子文档(子文档再调用子文档),需修改函数递归解析子文档中的
child路径; - 运行代码时建议使用全局环境
globalenv(),保证变量一致性。
内容的提问来源于stack exchange,提问作者Marcelo Avila
相关产品推荐
相关产品推荐

