【问题标题】:Setting local chunk options for a specific chunk in knitr?为knitr中的特定块设置本地块选项?
【发布时间】:2025-12-06 01:05:02
【问题描述】:

我正在使用knitr 来编织 RMarkdown,我曾多次想以编程方式添加代码块,但未能找到令人满意的方法。假设我想让knitr 在文件完成编织时播放声音。我解决这个问题的方法是这样的:

beep_on_knit <- function(beep_sound=3, sleep=3) {
  library(beepr)
  last_label <- tail(knitr::all_labels(),n=1)[[1]]
  knitr::knit_hooks$set(
    .beep_on_last_chunk =
      function(before, options) {
        if (options$label == last_label & !before) {
          beepr::beep(beep_sound)
          Sys.sleep(sleep)
          invisible(NULL)
        }
      })
  # Sets the options for every chunk so the hook will be run on them
  knitr::opts_chunk$set(.beep_on_last_chunk = TRUE)
}

但是,必须编辑每个块的块属性(即knitr::opts_chunk$set(.beep_on_last_chunk = TRUE) 意味着如果我将此函数添加到文档中,它将使以前缓存的每个块的缓存无效。

有没有办法预先设置特定块的选项?

【问题讨论】:

    标签: r r-markdown knitr chunks


    【解决方案1】:

    我不知道您为什么需要为文档全局设置knitr::opts_chunk$set(.beep_on_last_chunk = TRUE)。您是否可以仅在最后一个块上设置 .beep_on_last_chunk = TRUE 作为本地块选项?如果可以的话,您就不需要在钩子中测试if (options$label == last_label)

    或者,您可以考虑使用document 钩子,该钩子在整个文档被编织后执行,例如,

    knitr::knit_hooks$set(document = function(x) {
      beepr::beep(3)
      x
    })
    

    【讨论】:

    • 我只是在全局范围内设置了.beep_on_last_chunk,这样我制作的自定义钩子就会运行(并检查)每个块。在最后一个块中使用本地选项会使其“工作”,但我想提出一个自动工作的解决方案。否则,无论如何,我都可以自己将哔声功能放在最后一个块中。实际上,我确实最终使用了文档钩子来解决这个问题(因为如果最后一个块被缓存,上面的钩子永远不会检查它),但我仍然喜欢更好地以编程方式操作块的选项。谢谢!
    最近更新 更多