重定向R Markdown输出路径时触发'id未找到'错误,求解决方案
Rmd自定义knit函数后
id对象找不到的问题及解决 问题背景
我有一个Rmd文件,会调用执行数据获取与清洗的R脚本。初始YAML配置如下:
title: '' author: '' date: '' output: word_document: reference_docx: "docs/template.docx"
在Rmd的代码块里定义了id供脚本使用:
id <- 'MY-ID-01' library(packages needed) opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE, dpi = 300) source('scripts/data_cleaning.R') # 该脚本需要用到id对象
原本运行正常,但修改YAML添加自定义knit函数,把Word输出重定向到docs文件夹后:
title: '' author: '' date: '' output: word_document: reference_docx: "docs/template.docx" knit: (function(inputFile, encoding) { out_dir <- "docs"; rmarkdown::render(inputFile, encoding=encoding, output_dir=file.path(dirname(inputFile), out_dir))})
出现错误:
Error in eval(parse(test = test, keep.source = FALSE, envir) : object 'id' not found Calls: <Anonymous ... <Anonymous> -> %||% .transformer -> eval -> eval Execution halted
直接在data_cleaning.R里定义id,或者把脚本代码移入Rmd代码块,就能正常生成文件到docs文件夹。
问题原因
- 自定义
knit函数会触发rmarkdown::render在全新的子进程会话中执行,这个子进程不会继承原Rmd代码块执行时创建的环境变量(包括id)。 - 标准YAML配置下,Rmd是在当前会话中按顺序执行代码块,
id会被加载到全局环境,source的脚本能直接读取;但自定义knit函数启动的新会话里没有原会话的变量,因此脚本找不到id。
解决建议
方法1:显式传递环境给脚本
修改source调用时指定本地环境,让脚本能读取当前代码块的变量:source('scripts/data_cleaning.R', local = environment())方法2:在knit函数中定义或传递环境
把id定义在自定义knit函数里,或者指定render的envir参数让子进程继承环境:knit: (function(inputFile, encoding) { id <- 'MY-ID-01' out_dir <- "docs"; rmarkdown::render(inputFile, encoding=encoding, output_dir=file.path(dirname(inputFile), out_dir), envir = globalenv())})如果需要动态修改
id,可以从外部配置文件读取,避免硬编码。方法3:用Rmd参数传递
id
在YAML中定义参数,再在代码块中调用,这种方式更灵活:
YAML添加参数配置:params: id: 'MY-ID-01'Rmd代码块中读取参数:
id <- params$id source('scripts/data_cleaning.R', local = environment())渲染时还能通过
rmarkdown::render(..., params = list(id = "NEW-ID"))动态修改id。
内容的提问来源于stack exchange,提问作者B_to_the_P
相关产品推荐
相关产品推荐

