R: How to Prompt The User for Input from The Console

Creating a Prompt/Answer system to input data into R

Since this is supposed to be used as interactive code only, readline() can work for you. I did not add any error checking, but you'd probably want to do a fair amount of that to ensure proper input. Here's the core concept though:

fun <- function(){
x <- readline("What is the value of x?")
y <- readline("What is the value of y?")
t <- readline("What are the T values?")
v <- readline("What are the V values?")

x <- as.numeric(unlist(strsplit(x, ",")))
y <- as.numeric(unlist(strsplit(y, ",")))
t <- as.numeric(unlist(strsplit(t, ",")))
v <- as.numeric(unlist(strsplit(v, ",")))

out1 <- x + y
out2 <- t + v

return(list(out1, out2))

}

How to prompt the user for input from the console?

Readline does wait for the user's input. But the problem is that, in your case, when you run all of your code at once, R will treat 'n2<-readline(prompt="Enter skip 2: " )' as the user's input (it indeed is) to the first readline. This is the root of the problem.

So basically you have two choices to deal with your problem, the first is to find some specific package in R that halts R execution process when prompting; the second one is to stick to the R base, but only use readline in the ending block of your file. In your case, you can use a little trick like this:

{
n1<-readline(prompt="Enter skip 1: " )
n2<-readline(prompt="Enter skip 2: " )
n1<-as.integer(n1)
n2<-as.integer(n2)
}

The rationale behind this trick is this: when R read the thing between { and }, it will treat all of the things in between as a whole command, this is the ending block of the code, so it behaves like what you want. R will not feed part of this command to another part of the command, thus prevents the problem you met.

You can develop similar tricks yourself, like putting the readline in a function:

foo <- function(){
n1<-readline(prompt="Enter skip 1: " )
n2<-readline(prompt="Enter skip 2: " )
n1<-as.integer(n1)
n2<-as.integer(n2)
c(n1, n2)
}

foo()

In this case, the whole foo function will act as the ending block of your code, and all things work as you want. Hope this helps.

How to get a user input in command prompt and pass it to R

From the documentation of readline():

This can only be used in an interactive session. [...] In non-interactive use the result is as if the response was RETURN and the value is "".

For non-interactive use - when calling R from the command line - I think you've got two options:

  1. Use readLines(con = "stdin", n = 1) to read user input from the terminal.
  2. Use commandArgs(trailingOnly = TRUE) to supply the input as an argument from the command line when calling the script instead.

Under is more information.

1. Using readLines()

readLines() looks very similar to readline() which you're using, but is meant to read files line by line. If we instead of a file points it to the standard input (con = "stdin") it will read user input from the terminal. We set n = 1 so that it stops reading from the command line when you press Enter (that is, it only read one line).

Example

Use readLines() in a R-script:

# some-r-file.R

# This is our prompt, since readLines doesn't provide one
cat("Please write something: ")
args <- readLines(con = "stdin", n = 1)

writeLines(args[[1]], "output.txt")

Call the script:

Rscript.exe "some-r-file.R"

It will now ask you for your input. Here is a screen capture from PowerShell, where I supplied "Any text!".

Print screen from PowerShell

Then the output.txt will contain:

Any text!


2. UsingcommandArgs()

When calling an Rscript.exe from the terminal, you can add extra arguments. With commandArgs() you can capture these arguments and use them in your code.

Example:

Use commandArgs() in a R-script:

# some-r-file.R
args <- commandArgs(trailingOnly = TRUE)

writeLines(args[[1]], "output.txt")

Call the script:

Rscript.exe "some-r-file.R" "Any text!"

Then the output.txt will contain:

Any text!

Prompting for user input as part of a reference to an out-of-script function in R

The issue was in scoping the secondary function. It needs to be defined outside of the main block of the foo() code so that the readline is prompted to the user.

How to use ENTER as user input

A simple solution is:

for (i in 1:5){
readline(prompt=i) }

R script with user input from command line

Here is a total hack, repurposing a very specific purpose-built package for your more-general question:

library(getPass)
userInput<-function(question) {
n = 0
while(n < 1 ){
n <- getPass::getPass(msg = question)
n <- ifelse(grepl("\\D",n),-1,as.integer(n))
if(is.na(n)){break} # breaks when hit enter
}
return(n)
}

investedLow <- userInput("Invested value in low risk since last time: ")
print(investedLow)

Maybe the worst part about this is that getPass hides the user input. There must be a way to modify the source code to fix that.

Update: The getPass author pointed out that the solution could be as simple as using readLines slightly differently:

cat(question)
readLines(file("stdin"), n=1)


Related Topics



Leave a reply



Submit