31

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)
Jørgen R
  • 10,568
  • 7
  • 42
  • 59
Son
  • 5,295
  • 5
  • 19
  • 10
  • @Son : I edited your question to clarify the problem. Please, try to give complete information in your question about the errors you see. This will get you a faster response. – Joris Meys May 12 '11 at 13:56

2 Answers2

27

@Marek is very right. A few more remarks :

  • In general, you shouldn't be using scan() but readline() 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.

Joris Meys
  • 106,551
  • 31
  • 221
  • 263
  • A solution using `readlines()` instead of `scan` was already [offered](http://stackoverflow.com/questions/5951528/using-while-loop-with-logical-operators-and-and-or/5952295#5952295) to @Son. @Joris Meys +1 for mentioning `grepl()`. – Bernd Weiss May 12 '11 at 14:13
9

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.

Marek
  • 49,472
  • 15
  • 99
  • 121
  • Hi Joris, many thanks for your answer. It worked finally. It is good you did not put them together for me. After having struggle with it for about 4hours, it worked. I read this on the website-in the faqs:"When you have decided which answer is the most helpful to you, mark it as the accepted answer by clicking on the check box outline" BUT I CANNOT FIND THE CHECK BOX OUTLINE IN QUESTION. I equally thank Merek very much – Son May 12 '11 at 20:33