在 rmarkdown::render 之外初始化输出位置

Initialise output location outside of rmarkdown::render

帮助我找到了动态时间戳文件的方法,使用下面的 working 代码:

---
title: "Untitled"
author: "Jane Doe"
date: "`r Sys.Date()`"
output: word_document
knit: >
(function(input_file, encoding) {
# Render, keeping intermediate files for extracting front matter
md_dir <- tempdir()
output_file_temp <- rmarkdown::render(
  input = input_file,
  output_file = tempfile(),
  intermediates_dir = md_dir,
  clean = FALSE
)

# Get the rendered front matter from the intermediate Markdown file
md_file <- fs::path_ext_set(fs::path_file(input_file), ".knit.md")
metadata <- rmarkdown::yaml_front_matter(fs::path(md_dir, md_file))

# Build the output file name based on rendered metadata
output_name <- with(metadata, paste(title, "by", author, "on", date))

# Add the file extension and move to the working directory
output_ext <- fs::path_ext(output_file_temp)
output_file <- fs::path_ext_set(output_name, output_ext)
fs::file_move(output_file_temp, output_file)

message("Output moved to: ", output_file)
})
---

不过,我还想根据 projectmanagerprojectknitr 代码中指定输出位置。如果该文件夹尚不存在,则应创建该文件夹。

这可以按如下方式完成:link。我尝试结合这些解决方案。

我试过用几种不同的方法来做到这一点,但不知何故我无法让它工作。

需要的输出位置:

.../projectname/project")

我尝试使用 setwd 以及使用 file.path :

---
title: "Untitled"
author: "Jane Doe"
date: "`r Sys.Date()`"
output: word_document
projectmanager: "Earth Worm Jim"
project: "getstuffdone"
knit: >
  (function(input_file, encoding) {
    # Render, keeping intermediate files for extracting front matter
    md_dir <- tempdir()
    output_file_temp <- rmarkdown::render(
      input = input_file,
      output_file = tempfile(),
      intermediates_dir = md_dir,
      clean = FALSE
    )
    
    # Get the rendered front matter from the intermediate Markdown file
    md_file <- fs::path_ext_set(fs::path_file(input_file), ".knit.md")
    metadata <- rmarkdown::yaml_front_matter(fs::path(md_dir, md_file))
    # Tom: Specify the main directory in which to store all folders
    main_directory <- "Z:/Coding/R_scripts/Markdown/RMarkdown_out/"
    # Check current working directory
    print(getwd())
    # print(metadata)

    # Dynamically create a full path for the new file based on projectmanager and project
    out_dir <- with(metadata, paste0(main_directory, projectmanager, "/", project, "/"))
    print(out_dir)

    # Here I tried to set the working directory to the dynamically created wd
    setwd(out_dir)
    print(getwd())

    # Build output file name based on rendered metadata
    output_name <- with(metadata, paste(title, date, initials))
    print(output_name)
    output_dir = file.path(dirname(output_name), out_dir)
    print(output_dir)

    # path_ext() returns the last extension (if any) for a path
    output_ext <- fs::path_ext(output_file_temp) 
    print(output_ext)
    
    # replaces the extension with a new extension path_ext_set(path, ext)
    output_file <- fs::path_ext_set(output_name, output_ext) 
    print(output_file)

    fs::file_move(output_file_temp, output_file)
    message("Output file: ", output_file)
  })
---

你的方向是正确的,但如果需要的话,你还需要添加一个步骤来创建输出目录,并记得在移动渲染文件时使用创建的目录。

我会避免在脚本中更改工作目录。直接使用完整路径往往会使代码更容易理解。

这是添加了缺失步骤的修改版本:

---
title: "Untitled"
author: "Jane Doe"
date: "`r Sys.Date()`"
output: word_document
projectmanager: "Earth Worm Jim"
project: "getstuffdone"
knit: >
  (function(input_file, encoding) {
    # Render, keeping intermediate files for extracting front matter
    md_dir <- tempdir()
    rendered_file <- rmarkdown::render(
      input = input_file,
      output_file = tempfile(),
      intermediates_dir = md_dir,
      clean = FALSE
    )
    
    # Get the rendered front matter from the intermediate Markdown file
    md_file <- fs::path_ext_set(fs::path_file(input_file), ".knit.md")
    metadata <- rmarkdown::yaml_front_matter(fs::path(md_dir, md_file))
    
    # Directory that the output is relative to. Can be an absolute path.
    OUTPUT_ROOT <- "."
    
    # Build the output file name and directory based on rendered metadata
    output_dir <- with(metadata, fs::path(projectmanager, project))
    output_name <- with(metadata, paste(title, "by", author, "on", date))
    
    # Add the file extension
    output_ext <- fs::path_ext(rendered_file)
    output_file <- fs::path_ext_set(output_name, output_ext)
    
    # Combine parts to final path
    output_path <- fs::path(OUTPUT_ROOT, output_dir, output_file)
    
    # Create output directory if it doesn't exist
    output_path_dir <- fs::path_dir(output_path)
    if (!fs::dir_exists(output_path_dir)) {
      fs::dir_create(output_path_dir)
    }
    
    # Move render result to output location
    fs::file_move(rendered_file, output_path)
    message("Output moved to: ", output_path)
  })
---