I try to create Code snippet programmatically through a provided Parameter but Keep the target programming language dynamic.
What i tried:
Following https://stackoverflow.com/a/64855295/8538074
i know i could use opts <- knitr::opts_chunk$get()
which will include an engine opts$engine which could be tried
to bet set to "SQL".
I guess that sthg like that should work because of:
https://github.com/yihui/knitr-examples/blob/master/115-engine-sql.md
https://github.com/yihui/knitr-examples/blob/master/115-engine-sql.Rmd
(but i would need to render it from code since i handover the corresponding code string via the params of the rmarkdown file)
My best try:
---
title: "xx"
output: html_document
params:
code: list(language = "SQL", code_string = "SELECt * FROM tbl LIMIT 15")
---
```{r setup, include=FALSE}
hook <- knitr::hooks_html()$source
opts <- knitr::opts_chunk$get()
language <- params$code$code$language
opts$engine <- language
code_string <- params$code$code_string
cat(hook(code_string, options = opts))
```
Based on MartinĀ“s comment:
---
title: "xx"
output: html_document
params:
code: list(language = "SQL", code_string = "SELECT * FROM tbl LIMIT 15")
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r, results = 'asis', echo = F}
chunks <- eval(parse(text = params$code))
hook <- knitr::hooks_html()$source
opts <- knitr::opts_chunk$get()
opts$highlight <- FALSE
code_string <- chunks$code_string
cat(hook(code_string, options = opts))
```
Related
I am trying to make a RMarkdown report using bookdown::html_document2 to create numbered Fig. 1, Fig. 2, ... across the whole document. Here, I am using both the R-generated and the external figures. I have found that using include_graphics() will help to generate a proper Fig. X numbers, also including in numbering the external figures.
To get the script to work, I am declaring the root.dir = rprojroot::find_rstudio_root_file('C:/myRproject')) while my external figures are located within C:/myRproject/inImg. But in this case, R cannot find my external images anymore? Why is this and how can I properly claim the paths for my R Markdown input, and for external figures? Thank you!
Example:
---
title: "My awesome title"
author: "me"
date: "`r Sys.Date()`"
output:
bookdown::html_document2:
toc: true
toc_depth: 3
knit: (function(input, ...) {
rmarkdown::render(
input,
output_dir = "../outReports",
output_file = file.path("../outReports", glue::glue('test_{Sys.Date()}'
)))
})
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, tidy = TRUE, tidy.opts = list(comment = FALSE), message = F, warning = F)
knitr::opts_chunk$set(fig.width=6, fig.height=3)
library(knitr)
library(png)
```
```{css, echo=FALSE}
p.caption {
font-size: 0.8em;
}
```
```{r setup-root}
knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file('C:/myRproject'))
```
```{r read-libs, eval = TRUE, echo=FALSE, include = FALSE, warning = FALSE, error = FALSE }
# rm(list=ls())
getwd()
#### Source paths and functions -----------------------------------------------
source('myPaths.R') # already this one I can't find within the directory?
# Read pictures as part of teh R chunks
library(knitr)
library(png)
# Read Input data -------------------------------------------------------------------
#getwd()
load(file = "outData/dat1.Rdata")
```
## Including Plots
You can also embed plots, for example:
```{r, out.width = "50%", fig.cap = 'Add fig from internet'}
include_graphics("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/MC_Drei-Finger-Faultier.jpg/330px-MC_Drei-Finger-Faultier.jpg")
```
```{r add-extern-plot2, fig.cap = 'my numbered caption'}
# All defaults
img1_path <- "C:/myRproject/inImg/my_extern_fig.png"
img1 <- readPNG(img1_path, native = TRUE, info = TRUE)
attr(img1, "info")
include_graphics(img1_path)
```
I want to define a custom chunk hook to certain r-markdown chunks, which override certain chunk options (include and eval, basically).
Use case is that I add this chunk option to a chunk, which will hide code and output per default (include = FALSE) and evaluates the chunk only if a file exists eval = <some logic>. This works if I hardcode it (cf. to chunk export_disp_mpg_by_hand but not via a custom chunk option.
But regardless of how I try it, the options are not considered.
Code
---
title: "Chunks Options"
author: "Me"
output: html_document
---
```{r setup, include = FALSE, message = FALSE}
library(ggplot2)
library(knitr)
library(here)
image_path <- "figs"
if (!dir.exists(here(image_path))) {
dir.create(here(image_path))
}
knit_hooks$set(export_fig = function(before, options, envir) {
if (before) {
fn <- gsub("^export_", "", options$label)
options$include <- FALSE
options$eval <- !file.exists(here(image_path, paste0(fn, ".png")))
### Does not work either
## opts_current$set(include = FALSE,
## eval = !file.exists(here(image_path, paste0(fn, ".png"))))
}
options
})
```
# Plot
```{r make_plot}
(pl <- ggplot(mtcars, aes(disp, mpg)) +
geom_point())
```
```{r export_disp_mpg, export_fig = TRUE}
ggsave(here(image_path, "disp_mpg.png"), pl)
```
```{r export_disp_mpg_by_hand, include = FALSE, eval = !file.exists(here(image_path, "disp_mpg.png"))}
ggsave(here(image_path, "disp_mpg.png"), pl + geom_smooth(method = "lm"))
```
Expected Behaviour
Chunk export_disp_mpg should never be shown in the rendered output and the the file it creates should only be created if it is not existing.
So close, I found the solution. In case anybody is interested, I leave the question here with the follwong working answer.
Instead of using knit_hooks, one should use opts_hooks:
```{r setup, include = FALSE}
opts_hooks$set(export_fig = function(options) {
fn <- gsub("^export_", "", options$label)
options$include <- FALSE
options$eval <- !file.exists(here(image_path, paste0(fn, ".png")))
options
})
```
Is there a way to generate tables in a loop and set tab.id that can be later cross-referenced? Generating tables in a loop is trivial, but I don't know how to set ids and captions afterwards. Please, see the code below. Here I'm iterating over a list of R data.frames. In the last chunk I put the vector of ids (its lenght is 2) into chunk options - tab.id and tab.cap. This results in generation of two tables (good), but how to get the id of currently processed data.frame in the chunk?
---
output: officedown::rdocx_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
```{r}
library(flextable)
dfs <- list(
df1 = head(iris),
df2 = head(mtcars)
)
df_ids <- names(dfs)
```
```{r results='asis', tab.cap=paste("Result for item", df_ids), tab.id=paste0("tab_", df_ids),
tab.cap.style = "Table Caption"}
flextable(dfs[[???]]) # can current id be accessed somehow?
```
Another option is to use for loop to generate the tables. But how to set tab.id and tab.cap afterwards? Even a workaround solution can be fine for me.
You can probably set these values in a loop by using knitr::opts_chunk$set(). I would probably prefer set_caption in your case.
To print flextables in a loop inside an R Markdown document, use flextable_to_rmd(). See Looping in R Mardown documents.
---
output: officedown::rdocx_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
```{r}
library(flextable)
library(officer)
library(officedown)
library(magrittr)
dfs <- list(
df1 = head(iris),
df2 = head(mtcars)
)
df_ids <- names(dfs)
```
```{r results='asis'}
for(i in df_ids){
z <- flextable(dfs[[i]]) %>%
set_caption(caption = paste("Result for item", i),
style = "Table Caption",
autonum = run_autonum(seq_id = "tab", bkm = i))
flextable_to_rmd(z)
crossref_id <- sprintf("\\#ref(tab:%s)", i)
cat("\n\n\nA ref to table ", crossref_id, "\n\n\n\n")
}
```
I have the followin markdown:
---
title: "My report"
output: html_document
---
```{r setup, include=FALSE}
library(DT)
my_func <- function(x) {
#DT::datatable(x)
print(DT::datatable(x))
nrow(x)
}
```
```{r}
x <- my_func(mtcars)
print(x)
```
I want to display a DT from inside the function, but this function performs some calculations that I'm interested in the output of. So far it doesn't display the table. How can I force markdown to generate a table without returning it?
What about something like this:
---
title: "My report"
output: html_document
---
```{r setup, include=FALSE}
library(DT)
my_func <- function(x) {
res <- list(dt = DT::datatable(x),
nr = nrow(x))
class(res) <- "myfun"
invisible(res)
}
```
```{r}
x <- my_func(mtcars)
x$nr
```
```{r}
x$dt
```
Similar to how to create a loop that includes both a code chunk and text with knitr in R i try to get text and a Code snippet created by a Loop.
Something along this:
---
title: Sample
output: html_document
params:
test_data: list("x <- 2", "x <- 4")
---
for(nr in 1:3){
cat(paste0("## Heading ", nr))
```{r, results='asis', eval = FALSE, echo = TRUE}
params$test_data[[nr]]
```
}
Expected Output would be:
What i tried:
I tried to follow: https://stackoverflow.com/a/36381976/8538074. But printing "```" did not work for me.
You can make use of knitr hooks. Take the following MRE:
---
title: "Untitled"
output: html_document
params:
test_data: c("x <- 2", "x <- 4")
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r, results = 'asis', echo = F}
hook <- knitr::hooks_html()$source
opts <- knitr::opts_chunk$get()
chunks <- eval(parse(text = params$test_data))
for(nr in seq_along(chunks)){
cat(paste0("## Heading ", nr, "\n"))
cat(hook(chunks[nr], options = opts))
}
```
We get the default source hook and also the default chunk options. Then we get the test data, which is supplied as a string. Therefore we parse and evaluate that string.
In the loop we simply call the source hook on each element of the test data. Here is the result: