R包渲染R Markdown带图Word在非本地目录报错的解决方案咨询
问题根因
你的判断准确:rmarkdown/knitr渲染带图Word文档时,默认会在渲染工作目录下创建figure-docx文件夹存放临时png绘图文件,Windows UNC格式的网络共享盘路径和R的png()图形设备、递归目录创建函数存在兼容问题——即便你对目标输出目录有写入权限,png()设备直接写入UNC路径、递归创建多层父目录时仍会触发权限拒绝。纯表格类Word文档不需要生成外置图片资源,因此不会触发该故障。
解决方案
优先使用rmarkdown::render原生的intermediates_dir参数修复,该参数专门用于指定渲染过程中所有中间文件(含临时绘图、pandoc生成的文档片段)的存储路径,只需将其指向本地具备写入权限的目录(比如系统自带临时目录)即可,无需修改Rmd模板内容。
方法1:配置intermediates_dir(改动最小,推荐)
仅需修改myFun函数,在rmarkdown::render调用时新增intermediates_dir参数指向本地临时目录即可,修改后完整代码如下:
myFun <- function(mydata, filename){ G <- ggplot2::ggplot(mydata, ggplot2::aes(x = A, y = B)) + ggplot2::geom_point() OutPath <- normalizePath(dirname(filename), mustWork = TRUE) FileName <- basename(filename) # 取系统本地临时目录,默认当前用户具备完整读写权限,会话结束自动清理 temp_inter_dir <- tempdir() rmarkdown::render( system.file("rmarkdown/templates/myplot/skeleton/skeleton.Rmd", package="mypackage"), output_dir = OutPath, output_file = FileName, intermediates_dir = temp_inter_dir, # 核心配置:所有中间文件存本地 envir = environment(), # 修复局部对象找不到的潜在问题,确保Rmd能读取到函数内的G quiet = TRUE ) }
实现逻辑:配置该参数后,rmarkdown会自动将模板文件拷贝到本地临时目录完成全部渲染流程,仅在最后一步将生成好的docx文件写入你指定的输出路径,完全规避网络共享盘对中间文件、图片写入的兼容问题。
方法2:手动指定knitr图片输出路径(适配旧版本rmarkdown)
如果使用的rmarkdown版本过低不支持intermediates_dir参数,可以在渲染前手动修改knitr的图片存储路径到本地临时目录,代码如下:
myFun <- function(mydata, filename){ G <- ggplot2::ggplot(mydata, ggplot2::aes(x = A, y = B)) + ggplot2::geom_point() OutPath <- normalizePath(dirname(filename), mustWork = TRUE) FileName <- basename(filename) # 创建本地临时图片目录 fig_temp_dir <- paste0(tempdir(), "/knitr-fig-cache/") if (!dir.exists(fig_temp_dir)) dir.create(fig_temp_dir, recursive = TRUE) # 临时修改绘图路径,函数退出时自动恢复原有配置,避免影响其他渲染任务 old_fig_path <- knitr::opts_chunk$get("fig.path") knitr::opts_chunk$set(fig.path = fig_temp_dir) on.exit(knitr::opts_chunk$set(fig.path = old_fig_path), add = TRUE) rmarkdown::render( system.file("rmarkdown/templates/myplot/skeleton/skeleton.Rmd", package="mypackage"), output_dir = OutPath, output_file = FileName, envir = environment(), quiet = TRUE ) }
注意事项
- 不要尝试将
fig.path配置为网络共享盘的其他路径,R的png()图形设备对UNC路径的兼容问题没有通用解法,存储到本地临时目录是稳定性最高的方案 - Mac/Linux系统挂载的网络盘出现同类问题时,上述两个方案同样适用,
tempdir()会自动适配对应系统的临时目录路径 - 代码中新增的
envir = environment()参数修复了原函数的潜在bug:原函数中G为函数内部局部变量,不指定渲染环境时,部分场景下Rmd会因找不到G对象报错。
内容的提问来源于stack exchange,提问作者shirewoman2
相关产品推荐
相关产品推荐

