I have code similar to the following, which is dynamically generated and stored in a variable:
---
title: "test"
author: "me"
date: "3 June 2019"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r, comment=""}
for (i in 1 : 3) {
cat('\n')
print(summary(iris[i*50 : 50, "Sepal.Length"] ))
}
```
Let's say it's stored in a variable named rmkdown_code
Now, I need to be able to execute the code in this variable and render it as html or pdf. I am aware of the results = asis options, and I've tried different variations of it. But still, I'm not able to get the above code to render in html. The html page comes up in rstudio, and it shows the contents of rmkdown_code variable. It's just not executing it.
I need the content of rmkdown_code to be rendered as though it was from a flat file.
I have tried the following, none of which worked. Some formatted the text better, but the graph is not plotted. I would like to avoid writing the content of the rmkdown_code variable to a flat file.
```{r,echo=FALSE,eval=TRUE}
knitr::knit_expand(text=rmkdown_code)
#eval(parse(text = rmkdown_code))
#eval(c(paste0("- `", rmkdown_code, "`"), sep = "\n"))
#eval(knitr::asis_output(rmkdown_code))
#res <- knitr::knit_expand(text=rmkdown_code);knitr::knit(text=res, quiet=F)
# knitr::inline_expr("2+2")
```
output of dput(rmarkdown):
## "---\ntitle: \"test\"\nauthor: \"me\"\ndate: \"3 June 2019\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n```\n\n```{r, comment=\"\"}\nfor (i in 1 : 3) { \n cat('\\n') \n print(summary(iris[i*50 : 50, \"Sepal.Length\"] ))\n}\n```\n"
Here's a solution, not sure if it's ideal for your use case but it does successfully render rmkdown_code as an HTML report.
Be sure that you set your working directory or are working in a project, because the .rmd will render to your current wd.
rmkdown_code <- "---\ntitle: \"test\"\nauthor: \"me\"\ndate: \"3 June 2019\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n```\n\n```{r, comment=\"\"}\nfor (i in 1 : 3) { \n cat('\\n') \n print(summary(iris[i*50 : 50, \"Sepal.Length\"] ))\n}\n```\n"
render_func <- function(x){
writeLines(x, "temp.rmd")
rmarkdown::render("temp.rmd")
}
render_func(rmkdown_code)
This gives us:
Related
I have recently decided to use pagedown package in producing pdf and html outputs and therefore installed the library. I am trying to run the very simple Rmd file that comes as default when I choose to use pagedown file as my new file in the RStudio.
Here is the Rmd file content if you would like to see;
---
title: "A Multi-page HTML Document"
author: "Yihui Xie and Romain Lesur"
date: "`r Sys.Date()`"
output:
pagedown::html_paged:
number_sections: FALSE
# uncomment this line to produce HTML and PDF in RStudio:
knit: pagedown::chrome_print
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Introduction
This is an example of a multi-page HTML document with some options shown in YAML header. See https://pagedown.rbind.io for the full documentation. The rest of this document is random text.
# Random text
```{r, results='asis', echo = FALSE}
random_markdown = function(len = 100) {
uri = knitr::image_uri(file.path(R.home('doc'), 'html', 'logo.jpg'))
text = function(len) {
trimws(paste(sample(c(letters, rep(' ', 10)), len, TRUE), collapse = ''))
}
id = function() paste(sample(letters, 8, TRUE), collapse = '')
figure = function(i = id()) {
sprintf('![(#fig:%s)The R logo.](%s){width=%d%%}', i, uri, sample(20:60, 1))
}
tab = paste(knitr::kable(head(mtcars[, 1:5])), collapse = '\n')
table = function(i = id()) {
c(sprintf('Table: (#tab:%s)A table example.', i), tab)
}
unlist(lapply(seq_len(len), function(i) {
if (i %% 20 == 0) return(paste('#', text(sample(10:30, 1))))
if (i %% 10 == 0) return(paste('##', text(sample(10:30, 1))))
# insure some elements
if (i == 3) return(text(50))
if (i == 4) return(figure("md-fig"))
if (i == 5) return(text(50))
if (i == 6) return(table("md-tab"))
# then random
type = sample(1:3, 1, prob = c(.9, .03, .07))
switch(type, text(sample(50:300, 1)), figure(), table())
}))
}
cat(random_markdown(), sep = '\n\n')
# Knitr inserted Figures and tables
## Simple graphics
```
Until here, R markdown can run the document well. However, when I tried to add the following two code chunks, the document fails to run.
``` {r simple-graphic, fig.cap = 'A very simple plot'}
plot(1)
```
## Simple tables
```{r simple-table}
knitr::kable(head(mtcars, 3), caption = "A Simple table")
```
And here is the error I get;
Error in force(expr) : Failed to generate output in 30 seconds (timeout).
Calls: <Anonymous> -> with_temp_loop_maybe -> with_loop -> force
Closing websocket connection
Closing browser
Cleaning browser working directory
Closing local webserver
I do not understand why the document does not fail to run in the first phase, while it fails to run in the second step. I tried to find a solution through web. I hope I am clear regarding my problem and I look forward to your reply. Thank you for your understanding beforehand.
If you just remove knit: pagedown::chrome_print the document will render to HTML just fine, Then from here, you can "print to PDF" from the browser to get both an HTML and a PDF doc of the output
---
title: "A Multi-page HTML Document"
author: "Yihui Xie and Romain Lesur"
date: "`r Sys.Date()`"
output:
pagedown::html_paged:
number_sections: FALSE
---
I think the issue might be your are specifying 2 different output formats, and Rmarkdown is taking a long time to render these
There is a similar issue discussed here the advice was to increase the timeout value, as it's default is 30 seconds until the process is fails out. and another similar issue here... but to be honest, I was not able to correct apply the timeout argument in chrome_print
I have some R code in a package. I don't want to copy that code, but I want to display it in a pretty way in Word with syntax highlighting without any manual steps.
I looked at styler::style_text in combination of capture.output and that looks nice in the browser, but all the formatting is lost when knitting to Word. Is there some way to preserve it? I'm thinking the best thing would be to have Word native styling but the next best (acceptable) thing would be to somehow render the output to an image and include that. Has anyone done these things to document their code in a report?
show_code = function (fun) {
stopifnot(is.function(fun))
out = capture.output(fun)
n = length(out)
without_bytecode_and_env_lines = -1*c(n-1, n)
code = paste(out[without_bytecode_and_env_lines], collapse = "\n")
styler::style_text(code)
}
I believe you are trying to use syntax highlighting on the output of show_code and to do that, you simply need to use the options comment="" and class.output="r" and syntax highlighting will apply to the output.
---
title: "Source Code highlighting"
output:
word_document:
highlight: kate
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r echo=FALSE}
show_code = function (fun) {
stopifnot(is.function(fun))
out = capture.output(fun)
n = length(out)
without_bytecode_and_env_lines = c(n-1, n)
code = paste0(out[-without_bytecode_and_env_lines], collapse = "\n")
styler::style_text(code)
}
```
### The source code for `lm`
```{r comment='', echo=FALSE, class.output = "r"}
show_code(lm)
```
When I render an RMD automatically calling rmarkdown::render() within an R-Script, I run into trouble when - within the RMD itself - I try to access list-variables. In the example I want to loop through the content of the list variable and render a table for each list.
The first chunk
# This works
```{r, echo = FALSE, results='show'}
knitr::kable(a[[1]])
```
within the RMD renders successfully. However, the second section chunk
# This doesn't work
```{r, echo = FALSE, results='show'}
for (i in 1:length(a)) {
knitr::kable(a[[i]])
}
doesn't evaluate at all. There is not even an error/warning. The complete output renders as follows:
How can I successfully render the second chunk, named 'This doesn't work'? I'd expect to see 3 lists here, displaying the numbers 1:10, 11:20, 21:30.
Reproducible example: Save the following script as render.R:
setwd("C:/path_to_your_script_location/")
# generate a list containing 3 lists
a <- list(list(tour_id=1:10), list(tour_id=11:20), list(tour_id=21:30))
rmarkdown::render("test.Rmd", output_dir = "./", output_file = "out_test.html",
encoding = "UTF-8", quiet = TRUE)
and save the following content as test.Rmd:
---
title: Test
author: "Author"
date: "May 9th, 2018"
output: html_document
---
# This works
```{r, echo = FALSE, results='show'}
knitr::kable(a[[1]])
```
# This doesn't work
```{r, echo = FALSE, results='show'}
for (i in 1:length(a)) {
knitr::kable(a[[i]])
}
```
My solution: Change your last chunk to
```{r, echo = FALSE, results='asis'}
for (i in 1:length(a)) {
print(knitr::kable(a[[i]]))
}
```
I recently submitted a package to rOpenSci, and they prefer the use of message() rather than cat() for user-side console output. When I made the switch for my package, I noticed a disconcerting change in the formatting of the rendered vignettes. I have reproduced the problem in the following R Markdown report.
---
title: "MWE"
author: "Will Landau"
date: "11/20/2017"
output: html_document
---
```{r testcat}
for(x in LETTERS[1:3]){
cat(x, "\n")
}
```
```{r testmessage}
for(x in LETTERS[1:3]){
message(x)
}
```
```{r testmessage2}
for(x in LETTERS[1:3]){
message(x, "\n", appendLF = FALSE)
}
```
For the first code chunk, I get the desired output: all three lines string together in a single gray box.
## A
## B
## C
But for the second and third chunks, each line is given its own separate gray box.
## A
.
## B
.
## C
How do I keep using message() without chopping up the knitr output like this?
I think I solved it: knitr has a collapse chunk option. All I needed was to put this chunk before any of the other chunks.
```{r setup}
knitr::opts_chunk$set(collapse = TRUE)
```
The output is more condensed than I expected, but after some touching up, the formatting actually looks much better now.
You can try and build the string and put the message function outside the loop, like this:
```{r testmessage}
single_message <- c()
for(x in LETTERS[1:3]){
single_message <- paste(single_message , x, sep = "\n")
}
message(single_message )
```
Note that this example does add a newline at the start, you can prevent this with an extra if, or use the first element outside the loop to initialize single_message.
I'm working on a RMarkdown document that uses objects that take a long time to create and transform. The syntax is similar to this:
---
title: "Example"
author: "Test"
date: "October 29, 2015"
output: pdf_document
---
Example
```{r}
test_exc <- "NO"
if(exists("some_dta") == FALSE) {
set.seed(1)
# This data is big and messy to transform and I don't want to do it twice
some_dta <- data.frame(speed=runif(n = 1000),nonsense=runif(1000))
test_exc <- "YES"
}
```
You can also embed plots, for example:
```{r, echo=FALSE}
plot(some_dta)
```
Was the code executed: `r test_exc`
As suggested in the code above I would like to avoid repeated execution of the code if(exists("some_dta") == FALSE) { ... }. As illustrated in the code below the code within the loop executes:
I would like to know if there is a way of forcing RStudio markdown creation mechanism to understand that I those objects exists somewhere and there is no need to create them again.
You might want to use caching, as described in the online knitr documentation, e.g.:
---
title: "Example"
author: "Test"
date: "October 29, 2015"
output: pdf_document
---
Example
```{r chunk1,cache=TRUE}
set.seed(1)
# This data is big and messy to transform and I don't want to do it twice
some_dta <- data.frame(speed=runif(n = 1000),nonsense=runif(1000))
}
```
You could save your data to an .rds object and then run a check to see if that file exists
```{r}
if(!file.exists("some_dta.rds")) {
set.seed(1)
# This data is big and messy to transform and I don't want to do it twice
some_dta <- data.frame(speed=runif(n = 1000),nonsense=runif(1000))
saveRDS(some_dta, file='some_dta.rds')
} else {
some_dta <- readRDS('some_dta.rds')
}
```