0

私は、次の簡単なスクリプトと非常に類似しているいくつかのコードを使用しています。

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時間ほどのデバッグがなかったら、この問題は特定できなかったでしょう。バッチ処理スクリプトにかなりの数の関数が埋め込まれていました。そのような「落とし穴」を回避する方法でのコーディングに関する一般的なアドバイスはありますか?

4

1 に答える 1

2

通常、呼び出しに追加drop=FALSEするmtx[1,]と、単一行の抽出と、マトリックス構造を想定した後続の操作で発生する問題を回避できます。

result[index, 1:2] <- cbind(1, scores[1, 3:4, drop=FALSE])  # no error
# Also adding a third column to avoid dimension mismatch
scores <- matrix(rnorm(4*20), ncol=4,nrow=20)
result <- matrix(NA, ncol=3, nrow=20)
index <- as.logical(rbinom(20,1,.2))
result[index, 1:3] <- cbind(1, scores[index,3:4, drop=FALSE])

ゼロ行オブジェクトをゼロ行オブジェクトに割り当てる際のエラーを回避するために、どのように実行してほしいかがよくわかりません。代わりに確認する必要がありますlength(index)==0

(本当の問題は、3列のマトリックスを2列のターゲットに割り当てていたということです。ああ、ディメンションにない3番目の列に割り当てようとしていたことを除いて、それを修正しようとしたようです。)

于 2012-12-12T02:09:17.350 に答える