I'm trying to generate a rmarkdown chunk using code. I've read similar questions and their solutions, such as using pander or using cat. I just can't seem to generate it. I also tried knitting the output manually. Here's an example of a Rmd file:
---
title: "test"
output: pdf_document
---
## R Markdown
```{r, results='asis',echo=FALSE}
txt <- paste("```{r}",
"2+2",
"```")
pander::pander(txt)
```
When I knit this, I get a verbatim {r} 2+2. I would like to see the number four instead. In my real example, I'm using bookdown and trying to generate a block2 chunk.
Any ideas how to generate this chunk that gets evaluated as R code?
Does this do what you want?
## R Markdown
```{r, results='asis',echo=FALSE}
txt <- paste("```{r}",
2+2,
"```")
pander::pander(txt)
```
This evalutates to
```{r} 4 ```
in your markdown document.
You using a string literal "2+2" as opposed to the expression 2+2. This is the first issue, I guess.
If you want it correctly parsed you need to add an sep = "\n" argument to paste or manually add the newline breaks.
I.e.
## R Markdown
```{r, results='asis',echo=FALSE}
txt <- paste("```{r}\n",
2+2,
"\n```", sep = "")
pander::pander(txt)
```
This evalutates to
```{r}
4
```
which is interpreted as R code in the markdown document.
Related
I made a big Rmarkdown (.Rmd) file that contains only chunks of R codes. I'm wondering if there's a way to automatically generate a (.Rmd) file for every chunk or if I have to manually create a (.Rmd) file for every chunk I have (over 200 chunks).
Let's say I have this (.Rmd) file :
---
title: "Untitled"
output: html_document
date: '2022-08-13'
---
R Markdown
``{r cars}
summary(cars)
``
Including Plots
``{r pressure, echo=FALSE}
plot(pressure)
``
Is there a way to generate automatically a (.Rmd) file for the chuck r cars and another for the chunk r pressure?
Thanks in advance.
A possible solution is to use package parsemd:
library(parsermd)
rmd <- parse_rmd("x.Rmd")
rlabels <- c("cars", "pressure")
yaml <- rmd_select(rmd, has_type("rmd_yaml_list"))
for (i in rlabels)
{
rchunk <- rmd_select(rmd, all_of(i))
sink(paste0(i, ".Rmd"))
cat(as_document(yaml), sep = "\n")
cat(as_document(rchunk), sep = "\n")
sink()
}
The table prints nicely in markdown but is not present in the knitted html file. I noticed that it is classified as a list but don't know how to change it to an acceptable file type. The knitted output is not formatted as a table. I appreciate the help.
library("crosstable") #important package crosstable() function
library('dplyr')
library("flextable")
tbl1 = crosstable(mtcars2, c(1), by = 2) %>%
as_flextable(keep_id=FALSE)
print(tbl1)
According to ?print.flextable
Note also that a print method is used when flextable are used within R markdown documents. See knit_print.flextable().
Therefore, if we want to print in Rmarkdown, either use knitr::knit_print or remove the print as the ?knit_print.flextable documentation shows
You should not call this method directly. This function is used by the knitr package to automatically display a flextable in an "R Markdown" document from a chunk.
---
title: "Testing"
author: "akrun"
date: "09/12/2021"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r, echo = FALSE}
suppressPackageStartupMessages(library("crosstable")) #important package crosstable() function
suppressPackageStartupMessages(library('dplyr'))
suppressPackageStartupMessages(library("flextable"))
tbl1 = crosstable(mtcars2, c(1), by = 2) %>%
as_flextable(keep_id=FALSE)
# either use knit_print or remove the print wrapper
#knitr::knit_print(tbl1)
tbl1
```
-output
I'm after a way to render an Rmd document (that contains references to various "child" files) to a self-contained R Notebook without these dependencies.
At the moment, the .Rmd code chunks are located throughout a number of .R, .py and .sql files and are referenced in the report using
```{r extraction, include=FALSE, cache=FALSE}
knitr::read_chunk("myscript.R")
```
followed by
```{r chunk_from_myscript}
```
as documented here.
I've done this to avoid code duplication and to allow for running the source files separately however these code chunks are only executable in the report via a call to knit or render (when read_chunk is run and the code chunk is available).
Is there a way to spin-off an Rmd (prior to knitting) with
just these chunks populated?
This function
rmarkdown::render("report.Rmd", clean = FALSE)
almost gets there as it leaves the markdown files behind whilst removing extraction and populating chunk_from_myscript however as these files are straight markdown, the chunks are no longer executable and the chunk options are missing. It obviously also doesn't include chunks where eval=TRUE, echo=FALSE which would be needed to run the resulting notebook.
I've also looked at knitr::spin however this would mean disseminating the contents of the report to every source file and isn't terribly ideal.
Reprex
report.Rmd
---
title: 'Report'
---
```{r read_chunks, include=FALSE, cache=FALSE}
knitr::read_chunk("myscript.R")
```
Some documentation
```{r chunk_from_myscript}
```
Some more documentation
```{r chunk_two_from_myscript, eval=TRUE, echo=FALSE}
```
myscript.R
#' # MyScript
#'
#' This is a valid R source file which is formatted
#' using the `knitr::spin` style comments and code
#' chunks.
#' The file's code can be used in large .Rmd reports by
#' extracting the various chunks using `knitr::read_chunk` or
#' it can be spun into its own small commented .Rmd report
#' using `knitr::spin`
# ---- chunk_from_myscript
sessionInfo()
#' This is the second chunk
# ---- chunk_two_from_myscript
1 + 1
Desired Output
notebook.Rmd
---
title: 'Report'
---
Some documentation
```{r chunk_from_myscript}
sessionInfo()
```
Some more documentation
```{r chunk_two_from_myscript, eval=TRUE, echo=FALSE}
1 + 1
```
Working through your reprex I now better understand the issue you are trying to solve. You can knit into an output.Rmd to merge your report and scripts into a single markdown file.
Instead of using knitr::read_chunk, I've read in with knitr::spin to cat the asis output into another .Rmd file. Also note the params$final flag to allow rendering the final document when set as TRUE or allowing the knit to an intermediate .Rmd as FALSE by default.
report.Rmd
---
title: "Report"
params:
final: false
---
```{r load_chunk, include=FALSE}
chunk <- knitr::spin(text = readLines("myscript.R"), report = FALSE, knit = params$final)
```
Some documentation
```{r print_chunk, results='asis', echo=FALSE}
cat(chunk, sep = "\n")
```
to produce the intermediate file:
rmarkdown::render("report.Rmd", "output.Rmd")
output.Rmd
---
title: "Report"
---
Some documentation
```{r chunk_from_myscript, echo=TRUE}
sessionInfo()
```
With the secondary output.Rmd, you could continue with my original response below to render to html_notebook so that the document may be shared without needing to regenerate but still containing the source R markdown file.
To render the final document from report.Rmd you can use:
rmarkdown::render("report.Rmd", params = list(final = TRUE))
Original response
You need to include additional arguments to your render statement.
rmarkdown::render(
input = "output.Rmd",
output_format = "html_notebook",
output_file = "output.nb.html"
)
When you open the .nb.html file in RStudio the embedded .Rmd will be viewable in the editing pane.
Since neither knitr::knit nor rmarkdown::render seem suited to rendering to R markdown, I've managed to somewhat work around this by dynamically inserting the chunk text into each empty chunk and writing that to a new file:
library(magrittr)
library(stringr)
# Find the line numbers of every empty code chunk
get_empty_chunk_line_nums <- function(file_text){
# Create an Nx2 matrix where the rows correspond
# to code chunks and the columns are start/end line nums
mat <- file_text %>%
grep(pattern = "^```") %>%
matrix(ncol = 2, byrow = TRUE)
# Return the chunk line numbers where the end line number
# immediately follows the starting line (ie. chunk is empty)
empty_chunks <- mat[,1] + 1 == mat[,2]
mat[empty_chunks, 1]
}
# Substitute each empty code chunk with the code from `read_chunk`
replace_chunk_code <- function(this_chunk_num) {
this_chunk <- file_text[this_chunk_num]
# Extract the chunk alias
chunk_name <- stringr::str_match(this_chunk, "^```\\{\\w+ (\\w+)")[2]
# Replace the closing "```" with "<chunk code>\n```"
chunk_code <- paste0(knitr:::knit_code$get(chunk_name), collapse = "\n")
file_text[this_chunk_num + 1] %<>% {paste(chunk_code, ., sep = "\n")}
file_text
}
render_to_rmd <- function(input_file, output_file, source_files) {
lapply(source_files, knitr::read_chunk)
file_text <- readLines(input_file)
empty_chunks <- get_empty_chunk_line_nums(file_text)
for (chunk_num in empty_chunks){
file_text <- replace_chunk_code(file_text, chunk_num)
}
writeLines(file_text, output_file)
}
source_files <- c("myscript.R")
render_to_rmd("report.Rmd", "output.Rmd", source_files)
This has the added benefits of preserving chunk options and working
with Python and SQL chunks too since there is no requirement to evaluate
any chunks in this step.
Revised title to clarify focus.
We notice an anomaly that R markdown and data.table interact in a surprising way. Same does not happen when knitting LaTeX. Commands which not have a return within the R session do cause a return within the knitted markdown output. I trace the problem back to commands like the following, which do not produce an output in R,
````{r}
poolballs[ , weight2:=2 * weight]
```
but inside Rmarkdown, the output includes the full print of the poolballs DT. Same does not happen if we knit an equivalent chunk in LaTeX.
This produced some funny HTML output because I wrote chunks like this, intending to display only the first 5 lines
```{r}
poolballs[ , weight2:=2 * weight]
head(poolballs)
```
Markdown parses that as the equivalent of two chunks,
> poolballs[ , weight2:=2 * weight]
> poolballs
> head(poolballs)
Here's the markdown file to demonstrate
---
title: "Data Table Guide"
author:
- name: Paul Johnson
affiliation: Center for Research Methods and Data Analysis, University of Kansas
email: pauljohn#ku.edu
date: "`r format(Sys.time(), '%Y %B %d')`"
output:
html_document:
theme: united
highlight: haddock
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=TRUE, comment=NA)
options(width = 70)
```
```{r make_pb_dt}
set.seed(234234)
library(data.table)
poolballs <- data.table(
number = 1:15,
weight = rnorm(15, 45.7, 0.8),
diameter = c(3, 2.9, 3.1) #shows recyling
)
poolballs
```
I want the following to show only head in line 2
```{r}
poolballs[ , weight2:=2 * weight]
head(poolballs)
```
Compare the HTML output:
http://pj.freefaculty.org/scraps/mre-dt.html
I'm sorry if this is a known feature of markdown. I've coded around this wrinkle by hiding chunks, but it seems somewhat inconvenient. Today i'm curious enough to ask you about it. I wrote the same chunks in a LaTeX file and the funny DT output problem does not happen. I put link to PDF from LaTeX in http:/pj.freefaculty.org/scraps/mre-dt-3.pdf
In your final chunk, knitr sees that you have two objects that its attempting to print and you're getting the output for both. This isn't a feature, and has been addressed in a previous question.
If you want to only print the head of the first object in that chunk, your code should be head(poolballs[, weight2:=2 * weight])
It's fairly trivial to load external R scripts as per this R Sweave example:
<<external-code, cache=FALSE>>=
read_chunk('foo-bar.R')
#
Can the same be done for R Markdown?
Yes.
Put this at the top of your R Markdown file:
```{r setup, echo=FALSE}
opts_chunk$set(echo = FALSE, cache=FALSE)
read_chunk('../src/your_code.R')
```
Delimit your code with the following hints for knitr (just like #yihui does in the example):
## #knitr part1
plot(c(1,2,3),c(1,2,3))
## #knitr part2
plot(c(1,2,3),c(1,2,3))
In your R Markdown file, you can now have the snippets evaluated in-line:
Title
=====
Foo bar baz...
```{r part1}
```
More foo...
```{r part2}
```