How to ask the user for an integer at runtime, and recursively ask again if you didn't get one?

Viewed 49

I'm trying to write some code that does all of the following:

  1. At run time, asks, with an actual question (e.g. "How many PCs do you have? ") the user to type in an integer.
  2. Check if the user has given either an object of integer type or something that can be coerced in to that without error. This step must not require any sort of grep (e.g. that makes this solution invalid).
  3. Instead of giving any warning or errors if the input wasn't an integer, ask a new question that is repeated until they do give an integer (e.g. ask "Try again? " until an integer is given).
  4. Outputs this integer.

The solutions to similar questions appear to be to use either scan or readlines. I've ruled out scan because it likes to throw its own error messages, needs help from print to ask questions, and will ask for another input if given an invalid one even if you've told it to only try for one (e.g. scan(n = 1,quiet = TRUE) will ask for another input if you give it a bunch of letters). I've found that readlines is almost satisfactory, but because readlines treats its input as a string, I've been unable to write atrycatch block that satisfies requirement #3.

What are my options? It's looking like I've missed a simple solution.

1 Answers

We could either use a recursive function or a while or repeat loop to check if the answer is numeric

f1 <- function(question){


  flag <- TRUE
    while(flag) {
    out <- readline(paste0(question, "\n"))
    out1 <- type.convert(out, as.is = TRUE)
    if(is.numeric(out1)) flag <- FALSE
    }


    out1
}


v1 <- f1('how many PCs')
how many PCs
not sure
how many PCs
you asked the wrong person
how many PCs
#2432
how many PCs
20


v1
#[1] 20

Or another option is to convert to integer with as.integer. if there is any value that is not an integer/numeric, it would return NA. Using is.na as a logical condition, we can change the if line in the above code

Related