2

I am struggling to run this using the CRAN development environment (R: 3.4.0). I want to be able to run scripts (in one go rather than line by line) that request two numbers to be inputted in at the console window. I have used readline as many posters have recommended elsewhere.

The problem is, readline doesn't wait for user input; I'd expected, as was suggested in answers and documentation elsewhere, that this would behave like scanf in C but instead it just continues on regardless to the next line of code - you don't get a chance to input the data.

n1<-readline(prompt="Enter skip 1: " )
n2<-readline(prompt="Enter skip 2: " )
n1<-as.integer(n1)
n2<-as.integer(n2)
zx8754
  • 52,746
  • 12
  • 114
  • 209
cdcdcd
  • 547
  • 1
  • 5
  • 15
  • This is not really a good interaction pattern for R. If you are running scripts, it's better to pass in values as command line parameters. If you are expecting a user to fun interactively, let them pass arguments to functions you provide. – MrFlick May 16 '17 at 21:48
  • @MrFlick thanks for that. It is more for my own use. It is one of those things that I now just want to figure out where I am going wrong. Do you have any ideas? – cdcdcd May 16 '17 at 21:52
  • How exactly are you running this code? It sounds like you are running non-interactively. I just don't think it's possible to do what you ask with readline in that mode. R is very different than C. – MrFlick May 16 '17 at 21:54
  • Simply using he CRAN development environment (downloaded R for windows). You, have a console, I open a new script enter some code and select edit->run all. If I run line by line it works - but this virtually makes readline next to useless for almost all reasonable cases. – cdcdcd May 16 '17 at 22:00
  • 3
    In a way, there is nothing wrong with your code. `readline` works. The problem is the way that you are using it. When you select those four lines of code and run them, it is the same as cutting and pasting them into the console. After you execute the first `readline`, the console is looking for input and you give it input - the next line of code. If you just select the first line and run it, it will wait for your input. Then select only the second line and give it input. Finally, run the last two lines. – G5W May 16 '17 at 23:22
  • Thanks G5 that makes sense with what is happening. Is there any way I can run this, as a script, where it will execute the code as it was "designed"? If not then does make the function somewhat redundant for many implementations. – cdcdcd May 16 '17 at 23:29
  • Thanks G5 I just saw Consistency's answer that echoed yours. – cdcdcd May 16 '17 at 23:35

1 Answers1

11

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.

Consistency
  • 2,884
  • 15
  • 23
  • Thank you that worked. Fantastic, I had seen answers where it was put in a function but I thought it would just create the issue elsewhere. No more code rage. R has a much steeper learning curve than I imagined. – cdcdcd May 16 '17 at 23:33
  • I have a had a play and I am very disappointed to see that if you call anything after the function call I'm back to square one. So in short this seems to only ever work if your call is at the end of your script. I am getting to the point where I am about to just abandon R and go back to working with Python. I am a C programmer by trade but I am equally horrified by the stunted nature of the language as much as I'm impressed by its supporting code base. My experience learning Python was a pleasure this is truly awful. – cdcdcd May 17 '17 at 18:19
  • @cdcdcd Yes, if you need to run all of the code at once, the block that contains readline (either it is a function call or the {} or something else) has to be the last block. So for simplicity, just wrap all of your code with {} as my first example. It is not very elegant, but it works. – Consistency May 17 '17 at 18:26
  • @cdcdcd Since you are a C programmer and also knows python, maybe you can think of the block that contains readline as the main function or main while loop. Define all the functions you need (for data analysis or etc) and then call the main function at last to use the functions defined before or just wrap everything together by {} as the main function or main loop. – Consistency May 17 '17 at 18:35
  • Thanks again. I actually implemented something as you suggested. But this seems to be the tail wagging the dog. Perhaps the philosophy behind R is just at odds as to how I'd like to proceed. I can't see how I can call functions that need the input first. I understand that R tries to maintain the functional paradigm but whether file or input the state of the system will be dependent on external inputs. This seems a serious design flaw. – cdcdcd May 17 '17 at 19:07
  • 1
    @cdcdcd All I can say is that sometimes the "design flaw" is just another side of view of "design feature". R is tricky and is even unreasonable sometimes. I can list many weird "features" of R, they are useful but they will also cause serious bugs unexpectedly. I'm not sure why R feeds the script instead of waiting for user to input when prompting, maybe it is useful in some cases? Hope this helps. – Consistency May 17 '17 at 19:54
  • @Consistency This solution does not work when it is executing in between the program consisting of 300 lines of code. it just moves on the next statement. – Bhavneet sharma Jul 15 '19 at 09:10
  • @Bhavneetsharma Could you be more specific with your problem? Did you try to wrap your whole code into a function or a code block? And how do you execute the code? – Consistency Jul 21 '19 at 21:04
  • @Consistency Most of part in my code has wrapped into blocks or functions. I am using `source()` command to execute the entire script. But on execution, it skips that critical line where the user has to give some input for further required in execution. – Bhavneet sharma Jul 22 '19 at 04:31
  • @Bhavneetsharma I try some simple scripts which contain `readline` and use `source` to execute them, and all of them work. Would you mind coming up with some minimal reproducible example sharing with me? Thx. – Consistency Jul 23 '19 at 18:02