是否可以更改knitr中的fig.cap块选项?

问题描述 投票:0回答:1

我想更改 knitr 文档块中的

fig.cap
块选项。我倾向于编写大量如下所示的报告代码,以从小标题中取出绘图并使用相关的标题。

```{r fig, fig.cap=d_plot$caption}
d_plot <- [load the plotting tibble from prior work]
knit_print(d_plot$figure[[1]])
```

与我想做的类似的事情如下,但标题实际显示在其中。而且,如果它能够修改Fig.cap和Fig.scap,并且可以对多组数字进行多次

knit_print()
调用,那就更好了。

---
title: "Untitled"
author: "William Denney"
date: '2022-04-19'
output: pdf_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=FALSE, warning=FALSE, error=FALSE)
library(tidyverse)
library(knitr)
```

# Test

```{r functions, include=FALSE}
knit_print.fig_n_cap <- function(x) {
  lapply(x$figure, knit_print)
  opts_chunk$set(fig.cap=x$caption)
}

as_fig_n_cap <- function(x) {
  stopifnot(is.data.frame(x))
  stopifnot("figure" %in% names(x))
  stopifnot("caption" %in% names(x))
  class(x) <- c("fig_n_cap", class(x))
  x
}

p <- ggplot(data.frame(x=1:3, y=1:3), aes(x=x, y=y)) + geom_line()

d <- as_fig_n_cap(tibble(figure=list(p), caption="My caption"))
```

```{r}
knit_print(d)
```

r knitr
1个回答
0
投票

我认为在这里使用自定义输出块钩子来对输出进行后处理可能比自定义 knit_print 更好,因为钩子路线将允许 knitr 完成大量已经编程的繁重工作,例如保存临时图形、链接到它们并设置图形大小。

另一件事要考虑的是您要编织的格式,因为此示例仅适用于 html。需要对 pdf 输出执行类似的操作。

这是带有自定义钩子的示例 R Markdown 文档:

---
title: "Knitr Chunk Output Hook Example"
output: html_document
date: "2024-04-25"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)

local({
  hook_old <- knitr::knit_hooks$get("chunk")
  knitr::knit_hooks$set(chunk = function(x, options) {
    # regex to find each fig_n_cap object output
    figcap_regex <- stringr::regex(
      '```\\n## \\$figure\\n.+?## \\[1\\] "fig_n_cap"\\n```', 
      multiline = TRUE, 
      dotall = TRUE
    )
    
    # replace each fig_n_cap object output with
    # just the knitr figure code plus a caption line
    x <- stringr::str_replace_all(x, figcap_regex, ~ {
      # because knitr may generate md or html depending on settings,
      # try to extract both and use the one found
      img_md   <- stringr::str_extract(., "\\!.+>")
      img_html <- stringr::str_extract(., "<img.+/>")
      img_code <- ifelse(is.na(img_md), img_html, img_md)
      
      cap <- stringr::str_extract(., '## \\[1\\] "(.+)"\\n', 1)
      cap_html <- sprintf('<p class="caption">%s</p>', cap)
      
      paste(img_code, cap_html, sep = "\n")
    })
    
    hook_old(x, options)
  })
})
```

```{r}
gg_scatter_plot <- function(data) {
  data |> ggplot2::ggplot(ggplot2::aes(x, y)) + ggplot2::geom_point()
}

d_plot <- tibble::tibble(
  figure = list(
    data.frame(x = rnorm(1000), y = rnorm(1000)) |> gg_scatter_plot(),
    data.frame(x = runif(1000),  y = runif(1000)) |> gg_scatter_plot()
  ),
  caption = c("This is a caption.", "This is another caption.")
)

as_fig_n_cap <- function(x) {
  stopifnot(is.data.frame(x))
  stopifnot("figure" %in% names(x))
  stopifnot("caption" %in% names(x))
  class(x) <- "fig_n_cap"
  x
}

d_plot[1, ] |> as_fig_n_cap()

d_plot[2, ] |> as_fig_n_cap()
```
© www.soinside.com 2019 - 2024. All rights reserved.