web-dev-qa-db-ja.com

Rプログラムでユーザー入力を求める正しい方法は何ですか?

以下のプログラム(2つの部分に分かれています)は、別々に実行すると機能します。つまり、最初の部分をRコンソールに貼り付け、実行してから2番目の部分を貼り付けて実行します。しかし、それは私が望んでいる方法ではありません。プログラム全体を一度に実行したい。それを行うと、コンソールに次のエラーが表示されます:

1: 
Read 0 items
1: 
Read 0 items
Error in while ((n <= 0) | (acr <= 0) | (acr >= 1)) { : 
  argument is of length zero

問題を特定しようとしましたが、根本原因を見つけることができませんでした。誰かが私の助けに来ることができれば、私はうれしいです。

#**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)
31
Son

@マレクはとても正しい。さらにいくつかの発言:

  • 一般に、scan()を使用するのではなく、readline()を使用する必要があります。
  • コードを分割して、nで読むのに役立つものとacrで読むのに役立つものが明確になるようにしました。
  • ユーザーがEnterキーを押したときにプロンプ​​トに戻るか、正しい値が入力されるまで質問を再入力するかを考えます。
  • grepl()の機能を使用して、入力が正しい形式であるかどうかを確認できます。

正しいコントロールを含めて、考えられるすべての間違いをキャッチするために、次の構成は非常にクリーンで、コンソールにコピーしたときにコードを壊しません:

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
}

これは、人々が何も記入しないときに質問を終了する方法を示しています。 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))
}

これは、人々が何も記入しないときに質問を再質問する方法を示しています。 greplは、数字でもドットでもない文字を除外します。

27
Joris Meys

scanはすべてをコピーして貼り付けると、貼り付けられた行を入力として読み取るためです。

このツリー行をコンソールにコピーする場合

x <- scan(nmax=1)
1
2

x1になり、scanが読み込まれるので、インタラクションを待たないでください。

すべてを{}でラップする必要があります。

{
 x <- scan(nmax=1)
 1
 2
}

プログラムの両方の部分をラップする必要があります。より明確にするために:コンソールにコードを貼り付けるときは、}を最後のサインにする必要があります。

9
Marek