In R markdown, if I want to save cahce in some other directory than the file-directory. For this, in the chuck, I will specify
{r chunkName, cache=TRUE, cache.path=cache.path = "../cache_filename/"}
But how to avoid typing filename? Is there a way that it can take title name or filename without .Rmd?
knitr automatically sets the cache.path based on the input filename. If you want to do it differently, you could do something like this:
```{r}
origCache <- knitr::opts_chunk$get("cache.path")
base <- sub("_cache/.*$", "", origCache)
cat("The base of the filename is ", base)
knitr::opts_chunk$set(cache.path = paste0(base, "_new_cache"))
```
Now the cache will be set to the base part of the filename followed by "_new_cache".
Related
Solution in comments!
I'd like to have a template for the rmd file and have the template filled in with content, both R code chunks and regular text, according to the content of the spreadsheet.
Content to be used in code chunk
Text to be pasted after code chunk
Parametrized code 1
Description of event 1
Parametrized code 2
Description of event 2
Rmd output:
"""{r, echo = FALSE, comment = NA}
set.seed(rand_seed)
parametrized code 1
"""
Description of event 1
Thanks for your help!
I don't know if such a tool is available as of yet. However, you may be interested in taking a look at this topic https://bookdown.org/yihui/rmarkdown/parameterized-reports.html, from the R Markdown Definitive Guide.
EDIT:
Well, I came up with a simple solution. I'm not sure of how big your needs are for this logic, but for only a handful of chunks, maybe this script could help you. I tested it and it works.
instructions_set <- data.frame(
code_chunks <- c(
"a <- 50; print(a)",
"hist(iris$Sepal.Length)"
),
text_chunks <- c(
"I've just set the variable a to 50 and printed it.",
"This is a histogram of the variable Species in the Iris dataset."
)
)
file <- apply(instructions_set, MARGIN = 1, function(x) {
x[1] <- paste0("```{r}\n", x[1], "\n```")
return(
paste(x[1], x[2], "", sep = "\n")
)
})
readr::write_file(purrr::reduce(file, paste0), "test_file.Rmd")
I've found a solution using the knitrdata package. You can use the create_chunk and insert_chunk functions to convert strings to code chunks for rmarkdown.
My next step would be to load the strings into a data frame and iterate these two functions over the content of the data frame to create and insert multiple code chunks to the rmd file.
For the text part of the Rmd file, I'd use the writeLines function.
Here's a sample of the code chunk creation code I've put together:
library(knitrdata)
library(svDialogs)
#choose the blank template Rmd.file
input_file <- dlg_open(message = "Please select the blank Rmd file to use a template!" )$res
output_file <- paste(as.character(dlg_input( message = "Please name your output file!")$res), ".Rmd", sep = "")
#select line at which to insert the code chunk - I've chosen then last line of the file
insert_at <- length(readLines(input_file))
#takes string input and formats it as a chunk then returns it as a character vector
input_chunk <- create_chunk(text = "print('this is a test')", chunk_label = "Testing label creation", chunk_type = "r")
#inserts properly formatted chunk at the specified line of lines read from the target Rmd file
rmd_text <- insert_chunk(input_chunk, line = insert_at , rmd.file = input_file )
#since insert_chunk returns a character vector, this line writes it to a new Rmd file
writeLines(rmd_text,output_file)
There are already a few questions considering ggplots in RMarkdown but none has answered my question as how to put a ggplot into a table with kable() by knitr.
I ve tried this link:
How can I embed a plot within a RMarkdown table?
But have not had any luck so far. Any ideas?
The idea was to put all plots into a list with
a<-list(p1,p2,p3...)
and then having the table with
{r}kable(a)
Additional text should also be able to be included
b<-("x","y","z",...)
kable (c(a,b),col.names=c())
Thanks for your help
Frieder
I experimented some with this and the following is the best I could come up with. This is a complete markdown document you should be able to paste into RStudio and hit the Knit button.
Two relevant notes here.
Setting the file links directly into kable doesn't work as it is wrapped in html such that it is interpreted as text, so we need to gsub() it in. An alternative is to set kable(..., escape = FALSE), but it is a risk that other text might cause problems.
Also, the chunk option results = 'asis' is necessary to have the print(kab) return raw html.
I don't know if these are problems for the real application.
---
title: "Untitled"
author: "me"
date: "02/06/2020"
output: html_document
---
```{r, results = 'asis'}
library(ggplot2)
library(svglite)
n <- length(unique(iris$Species))
data <- split(iris, iris$Species)
# Create list of plots
plots <- lapply(data, function(df) {
ggplot(df, aes(Sepal.Width, Sepal.Length)) +
geom_point()
})
# Create temporary files
tmpfiles <- replicate(n, tempfile(fileext = ".svg"))
# Save plots as files, get HTML links
links <- mapply(function(plot, file) {
# Suit exact dimensions to your needs
ggsave(file, plot, device = "svg", width = 4, height = 3)
paste0('<figure><img src="', file, '" style = "width:100%"></figure>')
}, plot = plots, file = tmpfiles)
# Table formatting
tab <- data.frame(name = names(plots), fig = paste0("dummy", LETTERS[seq_len(n)]))
kab <- knitr::kable(tab, "html")
# Substitute dummy column for figure links
for (i in seq_len(n)) {
kab <- gsub(paste0("dummy", LETTERS[i]), links[i], kab, fixed = TRUE)
}
print(kab)
```
I have found my way around it as described in the link I posted.
I. Saved my plot as a picture
II. Used sprintf() to insert picture into table with this command from Rmarkdown:
![](path/to/file)
Poor, but it works. If anybody finds a solution, I will always be interested in smart coding.
I have an R Script that I would like to import from within a different R-script, manipulate it's content (search and replace) and save with a different extension (.rmd).
This is how the example.R File would look before manipulation:
# A title
# chunkstart
plot(1,1)
# chunkend
and this is how example.Rmd it would look after manipulation: replaced "# chunkstart" and "# chunkend" with ```{r} and ```, respectively.
# A title
```{r}
plot(1,1)
```
I've been searching for methods to do this, but so far have found none. Any ideas?
I'm sure that you can do it using regex with less lines of code.
However its should solve your problem.
library(magrittr)
readLines('example.R') %>%
stringr::str_replace("# chunkstart", "```{r}") %>%
stringr::str_replace("# chunkend", "```") %>%
writeLines("example.Rmd")
With the following lines of code you will be able to apply this "operation" in every .R file inside /path_to_some_directory
lapply(list.files('/path_to_some_directory', pattern = ".R$",
full.names = TRUE), function(data) {
readLines(data) %>%
stringr::str_replace("# chunkstart", "```{r}") %>%
stringr::str_replace("# chunkend", "```") %>%
writeLines(paste0(data, "md"))
})
Hope it helps!
I think ?knitr::spin is a relevant answer to the question (specifically asking for ideas), or at least a useful alternative to consider.
You'd have to slightly reformat the input, but the benefits would be a built-in, much richer and versatile way to deal with chunk options and formatting.
Here's what an annotated R script might look like (with spin's default regexs),
#' ## A title
#' first chunk
#- fig.width=10
plot(1,1)
# some text
#' another chunk
plot(2,2)
and the output Rmd reads,
## A title
first chunk
```{r fig.width=10}
plot(1,1)
# some text
```
another chunk
```{r }
plot(2,2)
```
I'm actually creating a shiny app. In that app, there is a download button which download a PDF file that depends of user's input.
So I use a .rnw file to do generate that PDF document. I just want to do a table (with tabular) which have a number of row that depends of app user's input.
So in my R chunck, i'd like to do something like that :
\begin{tabular}{c|c}
<<echo=FALSE>>=
for (index in 1:nrow(myData))
{
SomethingThatRunLaTeXCode(paste0("\hline ",
"\Sexpr{",myData[index,1],"}"," % ","\Sexpr{",myData[index,2],"}"))
}
\hline
\end{tabular}
#
As suggested by sebastian-c, a much better way to make such a table is to use the xtable package together with Knitr. To make the Knitr chunks understand TeX, use the chunk option results='asis'.
Since your data is a data.frame, it is straight-forward:
<<echo = FALSE, results = "asis">>=
## test data
set.seed(1)
df <- data.frame(Gaussian = rnorm(10), Exponential = rexp(10))
library(xtable)
cap = paste("My caption can span multiple lines and",
"can be arbitrarily long.")
xtable(df,caption = cap)
#
For full customization, use the function print.xtable on your xtable object.
<<echo = FALSE, results = "asis">>=
print.xtable(xtable(df),table.placement = "")
#
I have several pre-made figures, which I'd like to add to a latex document that I'm preparing with knitr.
What is the best strategy to add them using something like a for loop?
Thanks a lot!
My suggestion is to build a data frame to support the meta data about the needed LaTeX figure environments and then use mapply with a custom function to build the needed output. Here is an example .Rnw file
\documentclass{article}
\usepackage{hyperref,fullpage}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
}
\begin{document}
Thanks to \url{https://classroomclipart.com} for the graphics.
For displaying several pre-made figures you could write out the figure
environments yourself.
\begin{figure}[!h]
\centering
\caption{Explicit figure environment. \label{fig:00}}
\includegraphics[width=0.2\linewidth]{figs/man-working-on-a-computer-clipart-318.jpg}
\end{figure}
To create many figure environments, I would suggest building a data.frame with
captions, figure labels, options, and file paths:
<<>>=
myfigs <-
data.frame(caption = c("Bright Red Fall Foliage", "Chat 9", "Man On Computer"),
label = c("brff", "c9", "moc"),
option = c("width=0.1\\linewidth", "width=0.2\\linewidth", "width=0.3\\linewidth"),
path = c("figs/bright-red-fall-foliage-photo_8304-Edit.jpg",
"figs/chat-9-94.jpg",
"figs/man-working-on-a-computer-clipart-318.jpg"),
stringsAsFactors = FALSE)
myfigs
#
Build a function for creating a figure environment:
<<>>=
build_fig_env <- function(caption = "", label = "", option = "", path = "") {
cat(
sprintf("\\begin{figure}[!h]\n\\centering\n\\caption{%s \\label{fig:%s}}\n\\includegraphics[%s]{%s}\n\\end{figure}\n\n\n",
caption, label, option, path)
)
}
#
Now call the function using mapply. The mapply call is wrapped in a call to
invisible to suppress the irrelevant output.
<<results = "asis">>=
invisible(
mapply(build_fig_env,
caption = myfigs$caption,
label = myfigs$label,
option = myfigs$option,
path = myfigs$path,
SIMPLIFY = FALSE)
)
#
This is just one solution to your question.
\end{document}
The output looks like this:
Or you can view the pdf here