Closed epruesse closed 11 months ago
Thanks for the report. Using cache: true
is adding an option that triggers a .cell
div addition, which we don't want here in the tabset environment as you are using it.
Though it is working like this (after the fix I'll push), to improve your code you should have a look at knit_child()
and knit_expand()
. This will support much more complex output (like htmlwidget, or ggplot), because print
on kable()
works because this is markdown output, but it would not work with gt I believe.
Example: https://examples.quarto.pub/create-tabsets-panel-from-r-code/
For yours, this would be something like
---
title: "Tabset"
format: html
keep-md: true
---
```{r tabset-test}
#| results: asis
#| echo: false
#| panel: tabset
res <- lapply(seq(3), function(n) {
res <- knitr::knit_child(text = c(
"### table `r n`",
"",
"```{r}",
"#| cache: true",
"knitr::kable(data.frame(a=1:3, b=4:6))",
"```"), quiet = TRUE, envir = environment())
})
cat(unlist(res), sep = "\n")
This is basically an iteration with knitr::knit() on a template that looks like
````markdown
# Table `r n`
```{r}
#| cache: true
knitr::kable(data.frame(a=1:3, b=4:6))
Which the content you want to set in your tabsets as if you had written the all blocks
Hope this helps
Thank you @cderv! That was an impressively fast response and fix!
Thanks for the report. We would have not found this issue without a user report. So really thank you !
Here's a helper based on your code above to make the qmd more readable. In case it helps others.
Having this:
make_tab <- function(title, expr, envir = parent.frame(), cache = TRUE, print = TRUE) {
text = c(
paste("###", title),
"",
"```{r}",
if (cache) "#| cache: true",
deparse(substitute(expr)),
"```"
)
res <- knitr::knit_child(text = text, envir = envir, quiet = TRUE)
if (print) {
cat(res)
} else {
res
}
}
We can write:
```{r tabset-test}
#| results: asis
#| panel: tabset
for (n in seq(3)) {
make_tab("Table `r n`", {
knitr::kable(data.frame(a=1:3, b=5:7))
})
}
or
````qmd
```{r tabset-test-lapply}
#| results: asis
#| panel: tabset
tabs <- lapply(seq(3), \(n) {
make_tab("Table `r n`", {
knitr::kable(data.frame(a=1:3, b=5:7))
}, print = FALSE)
})
cat(unlist(tabs))
Bug description
Rendering multiple tabsets programmatically (which I find commonly useful to avoid repetition in writing when many plots need to be made available in report) only works with
#| cache: false
, not with#| cache: true
in R code blocks. Sinceggplot2
rendering takes quite a while, caching that dozen or more plots would help a lot. As is, all plots within such a tabset have to be rendered over and over with every change to the document.Steps to reproduce
This works:
:::
:::