I have a markdown file with 4 chunks of code, but all chunks depend on the same initial database. When I run each chunk separately no problem happens, but when I knit, the problem begins: the chunks don't identify the variables and dataset already in the environment.
I solve this problem by loading all the datasets again, but it's not efficient.
How I turn all the variables in the first chunk into global variables, i.e., available to all chunks.
```{r, echo=FALSE, message=FALSE, results='hide', warning=FALSE}
library(dplyr)
library(zoo)
library(tidyr)
variable1
variable2
```{r, echo=FALSE, message=FALSE, results='hide', warning=FALSE}
variable1 %>%
ggplot2(aes(x = date, y = whatever) +
geom_line()
For example, I have variables in the first chunk that will be plotted in another chunk. But these variables for some reason are not available.
Another problem: I have to load the packages in each chunk.
I appreciate it if someone can help!
You generally just use an initial block commonly labeled setup. And it does not even have to be a 'global' (in the sense of <<- assignment) variable: subsequent chunks are aware of earlier chunks.
Code
---
title: demo
---
```{r setup, echo=FALSE}
suppressMessages(library(zoo))
startDate <- as.Date("2020-01-01")
```
Some text.
```{r code}
data <- zoo(1:3, order.by=startDate + 0:2)
print(data)
```
Output
With apologies for a screenshot
Related
This works in a usual code chunk in R markdown:
m1_aov <- anova(m1)
m1_aov$`Sum Sq`[2] %>% round(3)
Unfortunately, using the latter in inline code breaks the knitr parser down
`r m1_aov$`Sum Sq`[2] %>% round(3)`
Indeed, it also breaks Stackoverflow.
I looked at this related question but could not infer a working solution to my problem. Any hint?
Expanding the comment with a working example:
---
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r}
a <- tibble::tibble(`a column` = 1:10) # using tibble to get a column name with a white space
m <- mean(a$`a column`)
```
Mean is `r m`
To me this looks like a neat trick because it avoids to include unecessary long code inside the text, and do not create the problem you are facing at the (small) cost of creating new objects.
The output:
I have an R code that generates several plots and tables from my data. I want to write a report in Rmarkdown in which i want to include just the plots and the tables without rewriting the R code. One way is to use 'read_chunk' function but it does not serve my purpose. Following is a simple example of what i need.
Suppose I have the following R script 'Example.r'
x <- 1:4
y <- sin(x)
####----Table
table <- cbind(x,y)
####----Plot
plot_1 <- plot(x,y)
Now in my R markdown file i want the following:
```{r echo=FALSE, cache=FALSE}
knitr::read_chunk('Example.r')
```
The following table shows the results:
```{r Table, echo=FALSE}
```
One can depict the result in a plot as well:
```{r Plot, echo=FALSE}
```
In the above example, i will not be able to insert either the table or the plot, since both need the input 'x' and 'y' to be defined before the table and the plot commands are run. Is there a way to implement this without hardcoding 'x' and 'y' two times?
Instead of sourcing an R script, here is my workflow which might be useful to you:
(sorry I feel it should be a comment but it gets a bit lengthy)
Keep a draft.rmd and a report.rmd side by side. the draft.rmd will be your workplace with exploratory data analysis. and the report.rmd will be your polished report
Gather results (like data.frames & ggplot objects) you want to put in the report in a list. Save the list as a result_181023.rda file. in a folder like data/
Load the saved result_181023.rda file in the report.rmd, draw your figures & print your tables and polish your report the way you like.
An example:
```{r data echo=FALSE, cache=FALSE}
# a list named result.list
# With a table result.list$df
# and a ggplot object: result.list$gg1
load("data/result_181023.rda")
```
The following table shows the results:
```{r Table, echo=FALSE}
knitr::kable(result.list$df)
```
One can depict the result in a plot as well:
```{r Plot, echo=FALSE}
result.list$gg1
```
I have been running some small R tutorials / workshops for which I keep my 'challenge scripts' in Rmarkdown documents. These contain free text and R-code blocks. Some of the code blocks are prefilled (eg, to set up datasets for later use), whereas some are there for the attendees to fill-in code during the workshop.
For each challenge script, I have a solution script. The latter contains all the free text of the former, but any challenge-blocks have been filled in (there's an example of a solutions workbook here).
I don't really want to keep two closely related copies of the same file (the challenge and the solutions workbook). So I was wondering if there's an easy way to construct my challenge scripts from my solutions scripts (or the solutions script from a challenge-script and an R-script containing just the solution blocks).
For example, is there an easy way to replace all named code-blocks in one Rmarkdown file with the correspondingly-named code block from another rmarkdown file?
That is, if I have
challenge.Rmd
HEADER
INTRODUCTION
Today we're going to learn about sampling pseudo-random numbers in R
```{r challenge_1}
# Challenge 1: Make a histogram of 100 randomly-sampled
# normally-distributed values
```
BLAH BLAH
END_OF_FILE
solutions.Rmd
HEADER
```{r challenge_1}
# Challenge 1: Make a histogram of 100 randomly-sampled
# normally-distributed values
hist(rnorm(100))
```
END_OF_FILE
How do I replace challenge_1 from challenge.Rmd with challenge_1 from solutions.Rmd?
All the best
This is one approach:
challenge.Rmd
---
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
show_solution <- FALSE
```
```{r child="solution.Rmd", eval=show_solution}
```
Today we're going to learn about sampling pseudo-random numbers in R
```{r challenge_1}
# Challenge 1: Make a histogram of 100 randomly-sampled
# normally-distributed values
```
```{r challenge_1_s, eval=show_solution, echo=show_solution}
```
```{r challenge_2}
# Challenge 2: Make a histogram of 100 randomly-sampled
# uniform-distributed values
```
```{r challenge_2_s, eval=show_solution, echo=show_solution}
```
solution.Rmd
```{r challenge_1_s, eval=FALSE, echo=FALSE}
# Challenge 1: Make a histogram of 100 randomly-sampled
# normally-distributed values
hist(rnorm(100))
```
```{r challenge_2_s, eval=FALSE, echo=FALSE}
# Challenge 2: Make a histogram of 100 randomly-sampled
# uniform-distributed values
hist(runif(100))
```
With the show_solution parameter you can include or exclude the solution from you rmarkdown. The participants are not able to compile the document for show_solution = TRUE unless they have the solution.Rmd. For show_solution = FALSE there's no problem and it compiles nicely.
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.
Is there a standard way to include the computed values from variables early on in the written knitr report before those values are computed in the code itself? The purpose is to create an executive summary at the top of the report.
For example, something like this, where variable1 and variable2 are not defined until later:
---
title: "Untitled"
output: html_document
---
# Summary
The values from the analysis are `r variable1` and `r variable2`
## Section 1
In this section we compute some values. We find that the value of variable 1 is `r variable1`
```{r first code block}
variable1 <- cars[4, 2]
```
## Section 2
In this section we compute some more values. In this section we compute some values. We find that the value of variable 2 is `r variable2`
```{r second code block}
variable2 <- cars[5, 2]
```
A simple solution is to simply knit() the document twice from a fresh Rgui session.
The first time through, the inline R code will trigger some complaints about variables that can't be found, but the chunks will be evaluated, and the variables they return will be left in the global workspace. The second time through, the inline R code will find those variables and substitute in their values without complaint:
knit("eg.Rmd")
knit2html("eg.Rmd")
## RStudio users will need to explicitly set knit's environment, like so:
# knit("eg.Rmd", envir=.GlobalEnv)
# knit2html("eg.Rmd", envir=.GlobalEnv)
Note 1: In an earlier version of this answer, I had suggested doing knit(purl("eg.Rmd")); knit2html("eg.Rmd"). This had the (minor) advantage of not running the inline R code the first time through, but has the (potentially major) disadvantage of missing out on knitr caching capabilities.
Note 2 (for Rstudio users): RStudio necessitates an explicit envir=.GlobalEnv because, as documented here, it by default runs knit() in a separate process and environment. It default behavior aims to avoid touching anything in global environment, which means that the first run won't leave the needed variables lying around anywhere that the second run can find them.
Here is another approach, which uses brew + knit. The idea is to let knitr make a first pass on the document, and then running it through brew. You can automate this workflow by introducing the brew step as a document hook that is run after knitr is done with its magic. Note that you will have to use brew markup <%= variable %> to print values in place.
---
title: "Untitled"
output: html_document
---
# Summary
The values from the analysis are <%= variable1 %> and
<%= variable2 %>
## Section 1
In this section we compute some values. We find that the value of variable 1
is <%= variable1 %>
```{r first code block}
variable1 = cars[6, 2]
```
## Section 2
In this section we compute some more values. In this section we compute
some values. We find that the value of variable 2 is <%= variable2 %>
```{r second code block}
variable2 = cars[5, 2]
```
```{r cache = F}
require(knitr)
knit_hooks$set(document = function(x){
x1 = paste(x, collapse = '\n')
paste(capture.output(brew::brew(text = x1)), collapse = '\n')
})
```
This has become pretty easy using the ref.label chunk option. See below:
---
title: Report
output: html_document
---
```{r}
library(pixiedust)
options(pixiedust_print_method = "html")
```
### Executive Summary
```{r exec-summary, echo = FALSE, ref.label = c("model", "table")}
```
Now I can make reference to `fit` here, even though it isn't yet defined in the script. For example, a can get the slope for the `qsec` variable by calling `round(coef(fit)[2], 2)`, which yields 0.93.
Next, I want to show the full table of results. This is stored in the `fittab` object created in the `"table"` chunk.
```{r, echo = FALSE}
fittab
```
### Results
Then I need a chunk named `"model"` in which I define a model of some kind.
```{r model}
fit <- lm(mpg ~ qsec + wt, data = mtcars)
```
And lastly, I create the `"table"` chunk to generate `fittab`.
```{r table}
fittab <-
dust(fit) %>%
medley_model() %>%
medley_bw() %>%
sprinkle(pad = 4,
bg_pattern_by = "rows")
```
I work in knitr, and the following two-pass system works for me. I have two (invisible) code chunks, one at the top and one at the bottom. The one at the bottom saves the values of any variables I need to include in the text before they are actually computed in a file (statedata.R). The top chunk sets the variable values to something that stands out if they haven't been defined yet, and then (if it exists) it grabs the actual values from the stored file.
The script needs to be knit twice, as values will be available only after one pass through. Note that the second chunk erases the saved state file at the end of the second pass, so that any later changes to the script that affect the saved variables will have to be computed anew (so that we don't accidentally report old values from an earlier run of the script).
---
title: "Untitled"
output: html_document
---
```{r, echo=FALSE, results='hide'}
# grab saved computed values from earlier passes
if (!exists("variable1")) {
variable1 <- "UNDEFINED"
variable2 <- "UNDEFINED"
if (file.exists("statedata.R")) {
source("statedata.R")
}
}
# Summary
The values from the analysis are `r variable1` and `r variable2`
## Section 1
In this section we compute some values. We find that the value of variable 1 is `r variable1`
```{r first code block}
variable1 <- cars[4, 2]
```
## Section 2
In this section we compute some more values. In this section we compute some values. We find that the value of variable 2 is `r variable2`
```{r second code block}
variable2 <- cars[5, 2]
```
```{r save variables for summary,echo=FALSE,results='hide'}
if (!file.exists("statedata.R")) {
dump(c("variable1","variable2"), file="statedata.R")
} else {
file.remove("statedata.R")
}
```
Latex macros can solve this problem. See this answer to my related question.
\newcommand\body{
\section{Analysis}
<<>>=
x <- 2
#
Some text here
} % Finishes body
\section*{Executive Summary}
<<>>=
x
#
\body