私は、次の簡単なスクリプトと非常に類似しているいくつかのコードを使用しています。
scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=2, nrow=20)
index <- as.logical(rbinom(20,1,.2))
result[index, 1:3] <- cbind(1, scores[index,3:4])
ここで、indexは論理ベクトルであり、sum(index)
通常はより大きいです1
が、1
またはである場合もあります0
。
次の場合、スクリプトは失敗しますsum(index) == 1
。
> scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
> result <- matrix(NA, ncol=3, nrow=20)
> index <- c(rep(FALSE, 19),TRUE)
> result[index, 1:3] <- cbind(1, scores[index,3:4])
Error in result[index, 1:3] <- cbind(1, scores[index, 3:4]) :
number of items to replace is not a multiple of replacement length
> cbind(1, scores[index,3:4])
[,1] [,2]
[1,] 1 -0.1780255
[2,] 1 -0.6840048
> #should be:
> c(1, scores[index,3:4])
[1] 1.0000000 -0.1780255 -0.6840048
そしてどこでsum(index) ==0
:
> scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
> result <- matrix(NA, ncol=3, nrow=20)
> index <- rep(FALSE, 20)
> result[index, 1:3] <- cbind(1, scores[index,3:4])
Warning message:
In cbind(1, scores[index, 3:4]) :
number of rows of result is not a multiple of vector length (arg 1)
> #cbinding to a zero-row matrix returns an error
この問題の明らかな解決策は次のとおりです。
scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=3, nrow=20)
index <- as.logical(rbinom(20,1,.1))
if(sum(index) > 1){
result[index, 1:3] <- cbind(1, scores[index,3:4])
}else{
if(sum(index) ==1){
result[index, 1:3] <- c(1, scores[index,3:4])
}
}
ただし、一連のステートメントを記述せずにこのエラーを回避するためのコーディング方法に関するアドバイスに興味がありますif
。結果が常にnx3行列になるように、原子ベクトルをnx2行列または2長ベクトル(n = 1)にバインドするトリックはありますか?n = 0のときにスクリプトがエラーを生成せずにこれを実行できる場合は、追加のポイント。
1時間ほどのデバッグがなかったら、この問題は特定できなかったでしょう。バッチ処理スクリプトにかなりの数の関数が埋め込まれていました。そのような「落とし穴」を回避する方法でのコーディングに関する一般的なアドバイスはありますか?