Reputation: 372
I am using R markdown and Knitr using Rstudio.
I have the following R markdown file:
---
title: "Untitled"
author: ""
date: ""
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
#Load libraries
library(knitr)
library(ggplot2)
library(reshape2)
library(chron)
library(gridExtra)
#Get current directory
directory = getwd()
setwd(directory)
readname = function()#prompt user for the name and number of the site
{
n <- readline(prompt="Site name and number: ")
return(n)
}
prjName=readname()
print(prjName)
prjName2="TEST NAME"
prjName2
The code asks the user for a site name and number. I can run the chunk in R markdown and get the user input via the console and print it just fine. It is also stored as a string in global environment. When I knit the document however, I get the following result:
It appears that when knitting the document I can't print the user input string...
Any help with this would be much appreciated.
Upvotes: 5
Views: 10344
Reputation: 898
Paramaterized reports (see previous answers) are helpful for setting variables before rendering and are a much better practice than the approach described below (which in most scenarios should probably be avoided due to lack of reproducibility). However if (for some reason) you want the user to be prompted to input data part way through an Rmd being rendered, you can use utils::menu()
with graphics = TRUE
paired with informative warning()
or message()
outputs to the console.
Imagine the following setting:
rmarkdown::render()
manually from an IDE (approach doesn't work with Rstudio's knit button or when rendering from anything that doesn't support graphics) and want to (in certain instances) intervene mid-render.The example below uses a flag to either proceed or recreate the data if the mean of is above/below some threshold, but this could be any flag you may want to set that triggers a need for user input.
---
title: "Using menu() in an Rmd"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
```
```{r initial-values-and-parameters}
cut_point_mean <- 0.35
set.seed(12)
data <- runif(1:10)
```
```{r initial-parameters}
(dat_mean <- mean(data))
(wait_to_proceed <- dat_mean < cut_point_mean)
num_retry <- 0
```
```{r while-loop-check-distribution}
while(wait_to_proceed){
warning(paste("Mean of data is:", dat_mean,
"\nThis is greater than cut_point of:", cut_point_mean,
"\ndo you want to proceed to plotting or resample data?"),
immediate. = TRUE)
switch(menu(choices = c("Yes, proceed to plotting.", "No, resample output."),
graphics = TRUE,
title = "Read warning(s) on console before making selection") + 1,
stop("User must make a selection.\n"),
wait_to_proceed <- FALSE,
num_retry <- num_retry + 1
)
if(wait_to_proceed){
data <- runif(1:10)
dat_mean <- mean(data)
wait_to_proceed <- dat_mean < cut_point_mean
}
}
```
```{r}
print(paste("Number of times data regenerated:", num_retry))
print(dat_mean)
```
```{r}
plot(data)
```
Imagine the code chunks above represent an Rmd document named "test-file.Rmd". After rendering this via rmarkdown::render("test-file.Rmd")
the initial value for dat_mean
will be ~0.32 so you will be prompted with:
I'm not sure there are scenarios where you should use this approach. For most problems like this it would be better to work out a reliable solution and have this inputted via the params
argument in rmarkdown::render()
.
A potential scenario where you end-up taking this approach may be if you have an external data source that is not totally reliable and where the action you should take is unclear or you want to check something before continuing and (for some reason) you want to have this occur midway through rendering the Rmd (instead of prior to kicking it off)...
Upvotes: 2
Reputation: 44867
As Nathan said in a comment, you can't use readline
to get input in a knitr
document, because it's not interactive. But you can get user input using a "parameterized report" (see http://rmarkdown.rstudio.com/developer_parameterized_reports.html). For example,
---
title: "Untitled"
author: ""
date: ""
output: html_document
params:
prjName: "The project name"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
readname = function()# Get the project name
{
params$prjName
}
prjName=readname()
prjName
If you just knit this document, it will set prjName to "The project name". If you click on "knit with parameters" (or set params = "ask"
in a call to rmarkdown::render
), you'll be prompted for the value, with that as the default.
Upvotes: 2