What is the correct way to ask for user input in an R program?
Solution 1
@Marek is very right. A few more remarks :
- In general, you shouldn't be using
scan()
butreadline()
for this. - I'd split the code so it becomes clear what serves to read in n, and what serves to read in acr.
- think about whether you want to return to the prompt when people just press enter, or whether you want to reask the question until they fill in some correct value.
- you can use the power of
grepl()
to check whether the input is the right format.
To include the correct controls and catch all possible mistakes, the following construct is a lot cleaner and won't break your code when copied to the console :
while(n < 1 ){
n <- readline("enter a positive integer: ")
n <- ifelse(grepl("\\D",n),-1,as.integer(n))
if(is.na(n)){break} # breaks when hit enter
}
This shows how to terminate the question when people don't fill in anything. The grepl construct exludes any character that is not a digit, including the dot.
while(is.na(acr) | acr <= 0 | acr >= 1 ){
acr <- readline("and the average cancellation rate between 0 and 1 :")
acr <- ifelse(grepl("[^0-9.]",acr),-1,as.numeric(acr))
}
This shows how to re-ask the question when people don't fill in anything. The grepl excludes any character that is not a digit or a dot.
Solution 2
It's because when you copy and paste all then scan
reads pasted lines as input.
If you copy this tree lines to console
x <- scan(nmax=1)
1
2
x
become 1
, scan
don't wait for your interaction cause it got line to read.
You have to wrap everything in {}
:
{
x <- scan(nmax=1)
1
2
}
You have to wrap both parts of your program. To be more clear: when you paste your code to console }
should be last sign.
Son
Updated on February 13, 2020Comments
-
Son over 4 years
The my program below(which is in two parts) works if I run them separately – that is, if I paste the first part into the R Console, run it and then paste the second and run it. However, that is not how I want it. I want to run the whole program at once. If I do that it shows the following error in my console :
1: Read 0 items 1: Read 0 items Error in while ((n <= 0) | (acr <= 0) | (acr >= 1)) { : argument is of length zero
I have tried to identify the problem but I have not been able find the root cause. I would be more than glad, if someone could come to my aid.
#**FIRST PART OF THE PROGRAM** n <- -2 acr <- -2 while((n<=0) | (acr<=0) | (acr>=1)) { print("enter a positive integer and the average cancellation rate between 0 and 1 you want") try(n <- scan(what=integer(), nmax=1), silent=TRUE) try(acr <- scan(what=double(), nmax=1), silent=TRUE) } #**SECOND PART OF THE PROGRAM** bygrace <- read.table("C:\\MyRfolder\\bygrace.txt", header=FALSE) r <- nrow(bygrace) c <- ncol(bygrace) copybygrace <- array(bygrace, dim=c(r, c)) copybygrace <- bygrace[-((n+1):r), ] write.table(copybygrace,file="C:\\MyRfolder\\copybygrace.txt", sep="\t") copybygrace <- read.table("C:\\MyRfolder\\copybygrace.txt", header=TRUE)