How can I use a variable as the chunk name? I have a child document which gets called a number of times, and I need to advance the chunk labels in such a manner than I can also cross reference them.
Something like this:
child.Rmd
```{r }
if(!exists('existing')) existing <- 0
existing = existing + 1
myChunk <- sprintf("myChunk-%s",existing)
```
## Analysis Routine `r existing`
```{r myChunk,echo = FALSE}
#DO SOMETHING, LIKE PLOT
```
master.Rmd
# Analysis Routines
Analysis for this can be seen in figures \ref{myChunk-1}, \ref{myChunk-2} and \ref{myChunk-3}
```{r child = 'child.Rmd'}
```
```{r child = 'child.Rmd'}
```
```{r child = 'child.Rmd'}
```
EDIT POTENTIAL SOLUTION
Here is one potential workaround, inspired by SQL injection of all things...
child.Rmd
```{r }
if(!exists('existing')) existing <- 0
existing = existing + 1
myChunk <- sprintf("myChunk-%s",existing)
```
## Analysis Routine `r existing`
```{r myChunk,echo = FALSE,fig.cap=sprintf("The Caption}\\label{%s",myChunk)}
#DO SOMETHING, LIKE PLOT
```
A suggestion to preknit the Rmd file into another Rmd file before knitting&rendering as follows
master.Rmd:
# Analysis Routines
Analysis for this can be seen in figures `r paste(paste0("\\ref{", CHUNK_NAME, 1:NUM_CHUNKS, "}"), collapse=", ")`
###
rmdTxt <- unlist(lapply(1:NUM_CHUNKS, function(n) {
c(paste0("## Analysis Routine ", n),
paste0("```{r ",CHUNK_NAME, n, ", child = 'child.Rmd'}"),
"```")
}))
writeLines(rmdTxt)
###
child.Rmd:
```{r,echo = FALSE}
plot(rnorm(100))
```
To knit & render the Rmd:
devtools::install_github("chinsoon12/PreKnitPostHTMLRender")
library(PreKnitPostHTMLRender) #requires version >= 0.1.1
NUM_CHUNKS <- 5
CHUNK_NAME <- "myChunk-"
preknit_knit_render_postrender("master.Rmd", "test__test.html")
Hope it helps. Cheers!
If you're getting to this level of complexity, I suggest you look at the brew package.
That provides a templating engine where you can dynamically create the Rmd for knitting.
You get to reference R variables in the outer brew environment, and build you dynamic Rmd from there.
Dynamic chunk names are possible with knitr::knit_expand(). Arguments are referenced in the child document, including in the chunk headers, using {{arg_name}}.
So my parent doc contains:
```{r child_include, results = "asis"}
###
# Generate a section for each dataset
###
species <- c("a", "b")
out <- lapply(species, function(sp) knitr::knit_expand("child.Rmd"))
res = knitr::knit_child(text = unlist(out), quiet = TRUE)
cat(res, sep = "\n")
```
And my child doc, which has no YAML header, contains:
# EDA for species {{sp}}
```{r getname-{{sp}}}
paste("The species is", "{{sp}}")
```
See here in the RMarkdown cookbook.
Related
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)
```
Below is the code that is presenting the problem.
I can't seem to find a way to have it not print the source data before the table, house. Is this a code chunk option issue such as not having include = False in the code? To produce, you would create a new R markdown document and then put the code below in the first two code chunks (usually gray background color).
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
pkgs <- c("tidyverse","tidyquant","RODBC", "RODBCDBI",
"spdplyr","rgdal","readxl","Rcpp",
"RcppRoll", "ggforce","scales", "DBI","ggthemes",
"cowplot","gt","data.table","gridExtra","ggrepel","htmltab","tigris","tidycensus")
loader <- function(x){
for( i in x ){
if(!require(i, character.only = TRUE) ){
install.packages(i, dependencies = TRUE)
require(i, character.only = TRUE)
}
}
}
loader(pkgs)
#lapply(pkgs,library,character.only = TRUE)
```
## Housing Price
```{r, echo=FALSE,comment=FALSE,message=FALSE}
# load data
dt <- fread("http://www.freddiemac.com/fmac-resources/research/docs/fmhpi_master_file.csv")
dt[,hpa_yoy:=Index_SA/shift(Index_SA,12)-1,.(GEO_Type,GEO_Code,GEO_Name)]
dt_nv<- dt[GEO_Name=="NV" & Year>2010,]
head(dt_nv)
dcast(dt_nv,Year~Month,value.var="hpa_yoy")
dt_nv[,mname:=factor(month.abb[Month],levels=month.abb)]
dt_tab <- dcast(dt_nv,Year~mname,value.var="hpa_yoy")
house<- gt(dt_tab) %>%
opt_row_striping()%>%
fmt_percent(
columns = c(month.abb),
decimals = 1,
use_seps = FALSE
) %>%
tab_header(title="Nevada House Price Growth",
subtitle="12-month % change in Freddie Mac House Price Index" )%>%
tab_options(
data_row.padding = px(9),
row_group.padding = px(9),
table.font.size = px(11),
source_notes.font.size = px(11),
source_notes.padding = px(1))
```
## Including Plots
Housing Prices
```{r, echo=FALSE, message=FALSE}
house
```
Really unclear what the question is and I am not installing all of these packages, but from what I can tell, you need to put include=FALSE into the header of the second chunk.
The lines:
dt[,hpa_yoy:=Index_SA/shift(Index_SA,12)-1,.(GEO_Type,GEO_Code,GEO_Name)]
and head(dt_nv)
that are causing problems because they are not assigned to any object, R is just printing the table described by these line, I think.
If you are desperate, make this code eval=FALSE and then copy the code into another chunk with include=FALSE so the first block is there for show, while the actual block is evaluated without being shown in the document.
I've been trying to generate a sequence of graph plots inside rmarkdown html compiler...
```{r, include=T, echo=F, fig.height=4, fig.width=10,warning=FALSE}
Here direct is the directory where the files are listed from
"files" is the list of files objects in the transaction form needed for the read.transaction function argument
direct <- "......"
files <- list.files(path = ".....")
for (i in 1:length(files)) {
tr<-read.transactions(file = paste(as.character(direct),"/",files[i],sep = ""),format = "basket",sep = ",")
rules <- apriori(tr, parameter = list(supp=sup, conf=confid))
rules <- sort(rules, by='count', decreasing = TRUE)
plotr <- plot(rules, method = "graph", engine = "htmlwidget")
}
```
I have tried print(plotr), printing just plot(rules,...) and nothing seems to work.
The problem is when I knit the markdown, the plot of the different transaction files doesn't pop up in the html generated by the .Rmd file. Consider that this loop is inside a function that runs inside the chunk.
It would be nice if someone could help me try to solve this problem. If its worth for something, I am trying to generate a report that returns different plot rules based on the apriori algorithm applied to the different files.
If anyone has any idea how this could be solved would be a great help, thank you.
To put multiple htmlWidgets in one RMarkdown chunk you need to create a taglist. Here is an example:
---
title: "Example RMarkdown with multiple arulesViz htmlWidgets in one chunk"
output: html_document
---
```{r}
library(arulesViz)
data(Groceries)
rules <- apriori(Groceries, parameter=list(support=0.001, confidence=0.8))
widget_list <- lapply(1:10, FUN = function(i)
plot(sample(rules, size = 10), method = "graph", engine = "htmlwidget"))
htmltools::tagList(widget_list)
```
You can also use a regular loop to populate the list. More information on this issue can be found at https://github.com/rstudio/DT/issues/67
To hide the messages from library and apriori in the resulting document you can do this:
---
title: "Example RMarkdown with multiple arulesViz htmlWidgets in one chunk"
output: html_document
---
<!-- Hide the messages for library -->
```{r, echo = FALSE, results = FALSE, warning = FALSE, message = FALSE}
library(arulesViz)
```
<!-- verbose = FALSE hides the progress report for apriori -->
```{r}
library(arulesViz)
data(Groceries)
rules <- apriori(Groceries, parameter=list(support=0.001, confidence=0.8),
control = list(verbose = FALSE))
widget_list <- lapply(1:10, FUN = function(i)
plot(sample(rules, size = 10), method = "graph", engine = "htmlwidget"))
htmltools::tagList(widget_list)
```
I've run my analyses in a source Rmd file and would like to knit a clean version from a final Rmd file using only a few of the chunks from the source. I've seen a few answers with regard to pulling all of the chunks from a source Rmd in Source code from Rmd file within another Rmd and How to source R Markdown file like `source('myfile.r')`?. I share the concern with these posts in that I don't want to port out a separate .R file, which seems to be the only way that read_chunk works.
I think I'm at the point where I can import the source Rmd, but now I'm not sure how to call specific chunks from it in the final Rmd. Here's a reproducible example:
SourceCode.Rmd
---
title: "Source Code"
output:
pdf_document:
latex_engine: xelatex
---
```{r}
# Load libraries
library(knitr) # Create tables
library(kableExtra) # Table formatting
# Create a dataframe
df <- data.frame(x = 1:10,
y = 11:20,
z = 21:30)
```
Some explanatory text
```{r table1}
# Potentially big block of stuff I don't want to have to copy/paste
# But I want it in the final document
kable(df, booktabs=TRUE,
caption="Big long title for whatever") %>%
kable_styling(latex_options=c("striped","HOLD_position")) %>%
column_spec(1, width="5cm") %>%
column_spec(2, width="2cm") %>%
column_spec(3, width="3cm")
```
[Some other text, plus a bunch of other chunks I don't need for anyone to see in the clean version.]
```{r}
save(df, file="Source.Rdata")
```
FinalDoc.Rmd
---
title: "Final Doc"
output:
pdf_document:
latex_engine: xelatex
---
```{r setup, include=FALSE}
# Load libraries and data
library(knitr) # Create tables
library(kableExtra) # Table formatting
opts_chunk$set(echo = FALSE)
load("Source.Rdata")
```
As far as I can tell, this is likely the best way to load up SourceCode.Rmd (from the first linked source above):
```{r}
options(knitr.duplicate.label = 'allow')
source_rmd2 <- function(file, local = FALSE, ...){
options(knitr.duplicate.label = 'allow')
tempR <- tempfile(tmpdir = ".", fileext = ".R")
on.exit(unlink(tempR))
knitr::purl(file, output=tempR, quiet = TRUE)
envir <- globalenv()
source(tempR, local = envir, ...)
}
source_rmd2("SourceCode.Rmd")
```
At this point, I'm at a loss as to how to call the specific chunk table1 from SourceCode.Rmd. I've tried the following as per instructions here with no success:
```{r table1}
```
```{r}
<<table1>>
```
The first seems to do nothing, and the second throws an unexpected input in "<<" error.
I wrote a function source_rmd_chunks() that sources chunk(s) by label name. See gist.
I am wanting to get more into using R markdown to perform analyses and generate output. Maybe I'm missing something simple, but I just want to be able to set the number of decimal places to show either 2 or 3 digits, depending on the output (e.g. t-statistic vs p-value).
I have previously used r options(digits=2), which works until the last digit you want to include is 0. I have gotten around this with the sprintf function, but having to specify for each number.
Is there a way to set a 'global' sprintf option so that for all numbers following, the same number of decimal places are shown?
Thank you,
Paul
Defining a format for inline code output is feasible with a knitr inline hook (hooks are the hidden gems of knitr).
Example #1
With this Rmd file, the number of decimals is controlled without using sprintf() in all inline codes:
---
title: "Use an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook:
knitr::knit_hooks$set(inline = function(x) {
x <- sprintf("%1.2f", x)
paste(x, collapse = ", ")
})
```
Now, get 3.14 with just writing `r pi`.
Example #2
Want to change the inline output format in some part of the report?
This Rmd file does the job:
---
title: "Use a closure and an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook
knitr::knit_hooks$set(inline = function(x) {
paste(custom_print(x), collapse = ", ")
})
# Define a function factory (from #eipi10 answer)
op <- function(d = 2) {
function(x) sprintf(paste0("%1.", d, "f"), x)
}
# Use a closure
custom_print <- op()
```
Now, get 3.14 with `r pi`...
```{r three-decimals, include=FALSE}
custom_print <- op(d = 3)
```
...and now 3.142 with `r pi`.
```{r more-decimals, include=FALSE}
custom_print <- op(d = 10)
```
Finally, get 3.1415926536 with `r pi`.
Example #3
Want to display different formats for t-statistic and p-value?
One can use S3 objects and an inline hook as in this Rmd file:
---
title: "Use S3 methods and an inline hook"
---
```{r setup, include=FALSE}
# Register an inline hook
knitr::knit_hooks$set(inline = function(x) {
paste(custom_print(x), collapse = ", ")
})
# Define a generic
custom_print <- function(x, ...) {
UseMethod("custom_print", x)
}
# Define a method for p-values
custom_print.p.value <- function(x, ...) paste(sprintf("%1.2f", x), collapse = ", ")
# Define a method for t-statistics
custom_print.t.stat <- function(x, ...) paste(sprintf("%1.1f", x), collapse = ", ")
```
Estimate models...
```{r fake-results, include=FALSE}
t <- c(2.581, -1.897)
class(t) <- "t.stat"
p <- c(0.025, 0.745)
class(p) <- "p.value"
```
Want to show T-stats: `r t` (get 2.6, -1.9).
And p-values: `r p` (get 0.03, 0.74).
Who said knitr is a wonderful package?
I don't know of a way to set a global option (though there may be one). But you can write a convenience output function to reduce the amount of typing. For example, put this function at the beginning of your document:
op = function(x, d=2) sprintf(paste0("%1.",d,"f"), x)
Then, later in your document, when you want to output numbers, you can, for example, do:
op(mtcars$mpg)
Or if you want 3 digits instead of the default 2, you can do:
op(mtcars$mpg, 3)
As found in the tutorial here by Yihui, this is how I've successfully implemented it in my Rmd file.
{r setup, include=FALSE, cache=FALSE}
options(scipen = 1, digits = 2) #set to two decimal