1

6列のdata.frameがあります。1 つ目は被験者用、2 つ目は実験のブロック用です。列 3、4、および 5 はバイナリ スコア (0 または 1) を計算するために必要な値で、6 列目に追加します (そのため、今、 0でいっぱいです)。

head(kfdblock3to9)
    subject time        gr       ugr      sdugr IL
40002.3   40002    3 0.4475618 0.3706000 0.02994533  0
40002.4   40002    4 0.4361786 0.3901111 0.01846110  0
40002.5   40002    5 0.4279880 0.4550000 0.02811839  0
40002.6   40002    6 0.4313647 0.4134444 0.04352974  0
40002.7   40002    7 0.4420889 0.4394286 0.02883143  0
40002.8   40002    8 0.4325227 0.3960000 0.06559222  0

forループでこれをやろうとしていますが、Rの初心者で、これに問題があります。私が実装しようとしているスコアリング式は次のとおりです。列 3 ($gr) の値が列 4 ($ugr) の値と列 5 ($sdugr) の値の .35 倍の差よりも小さい場合) の場合、サブジェクトは 1 を受け取り、それ以外の場合は 0 を受け取ります。

私がこれまでに試したことは次のとおりです。

for (i in kfdblock3to9$subject) {
     if (kfdblock3to9$gr<(kfdblock3to9$ugr-(.35*kfdblock3to9$sdugr))) 
                 kfdblock3to9$IL=1
         else kfdblock3to9$IL=0
    }

これにより、50 個の警告が表示され、すべて「条件の長さが 1 を超えており、最初の要素のみが使用されます」と書かれています。

その場合、インデックスに何か問題があると思いますが、それを理解できませんでした。どんな助けでも大歓迎です。

4

4 に答える 4

2

見てみましょwithinifelse

kfdblock3to9 <- 
within(kfdblock3to9,
  IL <- ifelse( gr < ugr - 0.35 * dugr, 1, 0)
)

within()それほど必要ではありませんが、コードがずっと読みやすく、理解しやすくなります。

なぜうまくいかないのですか?それはあなたの状態がベクトル化されているからです:試してみてください

kfdblock3to9$gr<(kfdblock3to9$ugr-(.35*kfdblock3to9$sdugr))

論理ベクトルが返されることがわかります。現在、if()句は一度に1つのブール値のみを処理できます。ベクトル化された結果がある場合は、ベクトル化されたソリューションが必要です。ifelse()

于 2012-05-22T11:54:55.640 に答える
2

あなたの問題を解決するために、私はこのようなものを提案します:

kfdblock3to9[, "IL"] <- ifelse(kfdblock3to9$gr < (kfdblock3to9$ugr-(0.35*kfdblock3to9$sdugr)), 1, 0);

(ベクトル化されたアプローチは、ほとんどの場合、ループよりも高速です。)

インデックスを尊重しないため、ループが間違っていますiiループ内の行にアクセスするには、を使用する必要があります。

for (i in seq(along=kfdblock3to9)) {
    cat("row:", i, kfdblock3to9[i, "subject"], "\n");
}
于 2012-05-22T11:54:59.437 に答える
2

あなたが望むのは論理テストです。loopしたがって、 、 、さらには の使用を避けることができifelse、単純に次のようにします。

kfdblock3to9$IL <- with(kfdblock3to9, gr < (ugr-0.35*sdugr))

IL 列には、1 または 0 ではなく、TRUE または FALSE が含まれます。整数を使用する場合は、次のようにします。

kfdblock3to9$IL <- as.integer(with(kfdblock3to9, gr < (ugr-0.35*sdugr)))
于 2012-05-22T11:58:16.607 に答える
0

この場合、ループを使用しないでください。将来ループを使用するときはいつでも、インデックスを使用する必要があります。

for (i in 1:length(kfdblock3to9$subject)) {
     if (kfdblock3to9[i,"gr"] < (kfdblock3to9[i, "ugr"] - .35 * kfdblock3to9[i, "sdugr"])) 
                 kfdblock3to9[i,"IL"]=1
     else  kfdblock3to9[i,"IL"]=0
}


kfdblock3to9
     subject time        gr       ugr      sdugr IL
40002.3   40002    3 0.4475618 0.3706000 0.02994533  0
40002.4   40002    4 0.4361786 0.3901111 0.01846110  0
40002.5   40002    5 0.4279880 0.4550000 0.02811839  1
40002.6   40002    6 0.4313647 0.4134444 0.04352974  0
40002.7   40002    7 0.4420889 0.4394286 0.02883143  0
40002.8   40002    8 0.4325227 0.3960000 0.06559222  0
于 2012-05-22T11:54:57.080 に答える