I am currently trying to utilize parameterized reports to allow users to input a dataset (and a few more variables of interest) that will then be fed into an R script that performs and outputs a variety of analyses. These datasets will have information on multiple subjects, and the goal is to produce one report for each subject within the dataset. Thus, I utilize a for loop that loops through the Usernames within the dataset (called map). I then input a .Rmd file which is responsible for the bulk of the analysis. The for loop essentially refers to this .Rmd file for the 50 or so subjects, and outputs the 50 or so reports.
for (id in unique(map$UserName)){
# bunch of code for processing
render(input = "../lib/scripthtml.Rmd",output_file = paste0('report.',
id, '.html'),"html_document",
output_dir = "Script_output", params = "ask") }
What I am currently trying to do is I am trying to utilize parameterized reports in Shiny to allow for the user to input their own dataset (map). Thus, I specified a parameter and utilized params = ask in the render step. The main issue lies here:
Since the render step is under the for loop, it is basically run for each subject. As a result, the params ask interface loads up 50 times, asking for the user to provide their dataset each time.
Is there anyway I can avoid this? How can I get a user to supply their dataset file as a parameter, then utilize it for all 50 reports?
All your variables may be passed through in your render command, I do this for thousands of reports currently.
YAML of .Rmd template
This may include default values for certain parameters depending on your requirements, for illustrative purposes I have left them as empty strings here.
---
params:
var1: ""
var2: ""
var3: ""
---
Loading data set
In shiny, you can have the file input once and re-use for each report. Passing elements of the data frame to the render command in the next section.
Pseudo code for render in for loop
for (i in 1:n) {
rmarkdown::render(
"template.Rmd",
params = list(
var1 = df$var1[i],
var2 = df$var2[i],
var3 = df$var3[i]
),
output_file = out_file
)
}
Note: within a shiny app, you will need to use df()$var1 assuming the file input will become a reactive function.
You can then use the parameters throughout your template using the params$var1 convention.
Related
I am trying to write an R script (to run from Rstudio by my students) that can accept a file of the phyloseq object type (is several tables connected to each other stored into one object) so I can use that object to run the code on. Since it seems like I cannot accept any phyloseq file directly, I decided to strip the file into 3 tables (of which are stored in the input file) like so
input <- as.data.frame(readline(prompt = "Enter phyloseq object name "))
input.taxtab <- as.data.frame(tax_table(input)) #tax_table is a ps-function that takes out the taxonomy table
input.otutab <- as.data.frame(input#otu_tab)
input.samdat <- as.data.frame(input#sam_data)
however, the obvious issues I see with my code are that the input file cannot store all the information, but it also (at the moment only seems to accept characters, i.e. it only takes the filename literally, not the file itself).
I have tried to get the data frames separately (by having 3 times the prompt input) but that doesn't coerce the file itself either. Here is a snippet of that:
input.taxtab <- as.data.frame(tax_table(readline(prompt = "Enter phyloseq object name ")))
Hope that someone can help me evolve my code to accept an actual file instead of its name
I have a LaTeX template, which I use with exam2pdf and where I would like to have the date of the exam as a parameter, whose value should be passed from R. Is that possible?
Yes, you can do this in two and a half ways:
(1) Via the header argument
You can set exams2pdf(..., header = ..., template = ...) where the content of the header is inserted into the template by replacing the %% \exinput{header} placeholder. Thus, when writing the template you can decide where exactly the header code ends up in the LaTeX code and you can make sure that the appropriate commands/packages are available. The header can then be specified in the following ways:
LaTeX code:
You can include something like header = "\\command{value}". There could be more complex pieces of LaTeX code, involving multiple lines, etc.
List of commands and values:
Instead of the full LaTeX code it might be more R-like to use a list specification like header = list(command = "value"). This is transformed internally to the LaTeX code mentioned above.
List of functions:
Finally you can also have a specification like header = list(command = valuefun) where valuefun is a function(i) so that you return a different string for the i-th random version of the exam.
List of all of the above:
A list consisting of unnamed character strings, named character string, and named functions can be used as well, combining all three specifications above.
More details are provided in the vignette("exams", package = "exams") which explains the design of exams2pdf() and how it can be leveraged. It also includes some examples which you can also copy to your working directory via exams_skeleton(write = "exams2pdf", ...). You can look at the exam.tex LaTeX template that is shipped with the package to see how you can insert a date and an ID (depending on the i-th iteration) into the PDF. For example:
exams2pdf("capitals.Rmd", template = "exam.tex",
header = list(Date = "2022-02-22", ID = function(i) paste("\\#", i)))
(2) Write a template generator
For the purposes from your question strategy (1) should be sufficient, I guess. However, if you need more control over what is done in the LaTeX template, then my recommendation would be to write a dynamic template generator. This is how exams2nops() is set up. It takes a lot of arguments that can be set by the user and then proceeds as follows:
Depending on the user arguments a corresponding nops.tex template is written in a temporary directory.
Then exams2pdf(..., template = "/path/to/nops.tex") is called to use this custom temporary template.
Some details, especially the counter for the i-th ID is still handled through the header argument.
I have an extensive R script that ranks stocks across 3 indices. I was able to automate it to run for each index and generate a Knitr HTML doc. I have 1 case where the script returns a value (using SVDialogs) and takes in an excel document to finish running. When I add in this case it complicates things since I can't run SVDialogs in RMarkdown.
Any tips on how to overcome this and take in user input while generating an HTML output?
indices <- c("TSX", "TSX Small Cap", "S&P 500")
latestdate <- as.Date('2019-01-17')
renderReport <- function(index, latestdate) {
rmarkdown::render("test.Rmd",
output_file = paste0(index," Score",".html"),
params=list(index=index,
latestdate=latestdate),
output_options = list(self_contained = FALSE, lib_dir = "libs"))
}
purrr::walk2(indices,latestdate, renderReport)
I had to redesign my code to be run from the script instead of markdown then use rmarkdown::render() to create the file. This still allows for user input.
I'm wondering if anyone can help me with a dilemma I'm having.
I have a dataset of around 300 individuals that contains some basic information about them (e.g. age, gender). I want to knit a separate R markdown report for each individual that details this basic information, in Word format. And then I want to save each report with their unique name.
The actual code which sits behind the report doesn't change, only the details of each individual. For example:
Report 1: "Sally is a female who is 34 years old". (Which I would want to save as Sally.doc)
Report 2: "Mike is a male who is 21 years old." (Saved as Mike.doc)
Etc, etc.
Is there a way I can do this without manually filtering the data, re-kniting the document, and then saving manually with unique names?
Thanks a lot!
Use the render function and pass a list of names to the function:
renderMyDocument <- function(name) {
rmarkdown::render("./printing_procedures/dagr_parent.Rmd",
params = list(names = name),
output_file = paste("~/document_", name, '.doc', sep = '')
)
}
lapply(names, renderMyDocument)
Then just make sure your RMD file can take the params argument via the YAML:
---
params:
names:
---
RStudio documentation on parameterized reports here: https://rmarkdown.rstudio.com/developer_parameterized_reports.html
I am using tableNominal{reporttools} to produce frequency tables. The way I understand it, tableNominal() produces latex code which has to be copied and pasted onto a text file and then saved as .tex. But is it possible to simple export the table produced as can be done in print(xtable(table), file="path/outfile.tex"))?
You may be able to use either latex or latexTranslate from the "Hmisc" package for this purpose. If you have the necessary program infrastructure the output gets sent to your TeX engine. (You may be able to improve the level of our answers by adding specific examples.)
Looks like that function does not return a character vector, so you need to use a strategy to capture the output from cat(). Using the example in the help page:
capture.output( TN <- tableNominal(vars = vars, weights = weights, group = group,
cap = "Table of nominal variables.", lab = "tab: nominal") ,
file="outfile.tex")