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 :
下面的my程序(分为两部分)如果我单独运行它们,也就是说,如果我将第一部分粘贴到R控制台,运行它,然后粘贴第二个并运行它。然而,这不是我想要的。我想立刻运行整个程序。如果我这样做,它会在我的控制台中显示以下错误:
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)
2 个解决方案
#1
25
@Marek is very right. A few more remarks :
@Marek是非常正确的。再说几句话:
- In general, you shouldn't be using
scan()
butreadline()
for this. - 一般来说,您不应该为此使用scan()而应该使用readline()。
- I'd split the code so it becomes clear what serves to read in n, and what serves to read in acr.
- 我将代码拆分,这样就可以清楚地知道在n中读什么,以及在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.
- 考虑当人们按下enter时,您是否希望返回到提示符,或者您是否希望重新分配问题,直到他们填入一些正确的值。
- you can use the power of
grepl()
to check whether the input is the right format. - 您可以使用grepl()的功能检查输入是否是正确的格式。
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.
这说明了当人们什么都不填时,如何终止这个问题。grepl构造会删除任何非数字的字符,包括点。
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.
这展示了当人们什么都不填的时候如何重新问问题。grepl排除任何不是数字或点的字符。
#2
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.
x变成1,扫描不要等待你的交互作用,因为它有行读。
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.
你必须把程序的两个部分都打包。更清楚的是:当您将代码粘贴到控制台}时,应该是最后一个符号。
#1
25
@Marek is very right. A few more remarks :
@Marek是非常正确的。再说几句话:
- In general, you shouldn't be using
scan()
butreadline()
for this. - 一般来说,您不应该为此使用scan()而应该使用readline()。
- I'd split the code so it becomes clear what serves to read in n, and what serves to read in acr.
- 我将代码拆分,这样就可以清楚地知道在n中读什么,以及在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.
- 考虑当人们按下enter时,您是否希望返回到提示符,或者您是否希望重新分配问题,直到他们填入一些正确的值。
- you can use the power of
grepl()
to check whether the input is the right format. - 您可以使用grepl()的功能检查输入是否是正确的格式。
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.
这说明了当人们什么都不填时,如何终止这个问题。grepl构造会删除任何非数字的字符,包括点。
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.
这展示了当人们什么都不填的时候如何重新问问题。grepl排除任何不是数字或点的字符。
#2
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.
x变成1,扫描不要等待你的交互作用,因为它有行读。
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.
你必须把程序的两个部分都打包。更清楚的是:当您将代码粘贴到控制台}时,应该是最后一个符号。