4

0 から 1 の間の値のベクトルを分類したいと考えています。したがって、これらの範囲の値を NA にしたいと考えています。

以下のコードを実行すると、警告が表示されます。

Error in if (x[i] > 0.001 & x[i] <= 0.01) x[i] = 0.01 :  missing value where TRUE/FALSE needed

コードを修正するにはどうすればよいですか?

for (i in 1:length(x))
  {
    if (x[i] <= .001)
      x[i] = NA
    if (x[i] > .001 & x[i] <= .01)
      x[i] = .01
    if (x[i] > .01 & x[i] <= .02)
      x[i] = .02
    if (x[i] > .02 & x[i] <= .03)
      x[i] = .03
    if (x[i] > .03 & x[i] <= .04)
      x[i] = .04
    if (x[i] > .04 & x[i] <= .05)
      x[i] = .05
    if (x[i] > .05 & x[i] <= .06)
      x[i] = .06
    if (x[i] > .06 & x[i] <= .07)
      x[i] = .07
    if (x[i] > .07 & x[i] <= .08)
      x[i] = .08
    if (x[i] > .08 & x[i] <= .09)
      x[i] = .09
    if (x[i] > .09 & x[i] <= .10)
      x[i] = .10
    if (x[i] > .10 & x[i] <= 1)
      x[i] = NA
  }
4

4 に答える 4

6

まず、いくつかのテスト データ:

set.seed(1); x = dnorm(rnorm(100))/(sample(1:100, 100, replace=TRUE))

サブセット化は、次の方法で実行できます。

x[x < .001] = NA
x[x > .1] = NA

または、1 つのステートメントに組み合わせることができます。

x[x < .001 | x > .1] = NA

更新:コードが機能しない理由に答えるには

そこに が見つかった場合問題が発生しているNAため、ループからそれらを削除しますforが、ループを実行する前にインデックスを付けて、後で削除できるようにします。

temp = which(x < .001 | x > .1) # Index the values you want to set as NA

forループから次の条件を削除します。

if (x[i] > .10 & x[i] <= 1)
  x[i] = NA
if (x[i] <= .001)
  x[i] = NA

forループを実行し、 を使用tempして値を に設定しNAますNA

x[temp] = NA

お役に立てれば!

更新 2: 2 行

x[x < .001 | x > .1] = NA
out <- ceiling(x*100)/100

floor を使用した AKE の提案とほとんど同じです。

これにより、ループと同じ結果が得られるはずです。

于 2012-06-23T13:06:38.217 に答える
1

明示的なループを使用する代わりにfor、非常に便利な などのベクトル化された関数を使用するようにしてくださいifelseNAsあなたの例でを再コーディングする方法は次のとおりです。

> x <- ifelse(x <= 0.001 | x > 0.1, NA, x)

他の値を再コード化するには、次の「巧妙な」使用を試すことができますcut

> x <- (cut(x, breaks=seq(0.01, 0.09, 0.01), labels=FALSE) / 100) + 0.01

より良い (そしてより透過的な) 方法がある可能性がありますが。R で明示的なループを避ける理由forは、ベクトル化された代替手段と比較すると非常に非効率的だからです。R Infernoは、これとその他の R のトリックとヒントについての優れた議論を提供します 。

于 2012-06-23T13:19:04.143 に答える
0

このfindInterval関数は、この非常に構造化された選択問題で生産的に使用できます。特定の間隔で値を「検索」または選択できるインデックスを生成します。

x <- rnorm(1000)
x <- c(NA, seq(0.1, 1, by=0.1), NA)[
            1+ findInterval(x, c(0.001, seq(0.1, 1, by=0.1)) ,rightmost.closed=TRUE) ]
#---------------
table(x)
x
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9   1 
 34  38  48  44  29  30  26  20  17  31 
> table(is.na(x))

FALSE  TRUE 
  317   683

rightmost.closed引数は、通常の左端の区間のクロージャをシフトしますが、この例では、ランダムな描画のいずれも境界上になかったため、問題ではありませんでした。ただし、通常、入力データを破棄することはお勧めできません。x元のデータのコピーであったことを願っています。これを行う別の方法は、を省略し、代わりに次のような2番目の引数1+で間隔を使用することです。findIntervalc(-Inf, 0.001, seq(0.1, 1, by=0.1) , Inf)

于 2012-06-23T13:51:49.903 に答える
0

あなたのソリューションは概念的には機能しますが、それは「ブルートフォース」です。つまり、多くのタイピングが必要であり、わずかに異なる問題に対応できず、実行も遅くなります。

R ではベクトルを使用できるため、ロジックが 0 から 1 の間の任意の数値に対して機能する場合は、0 から 1 の間の値のベクトルで機能するはずです。

次のようなことを試してください。

      y=((floor(100*x))       # all values < 0.01 map to 0
      if y>10 then y=0        # force values > 0.1 to 0
      if y>0, then (y+1)/100  # for non-zero values, map to the upper interval, then return to original scale.

1 行目は、0.01 未満のすべての値を 0 に押しつぶします。2 行目は、0.1 より大きいすべての値を 0 に押しつぶします。3 行目は、残りのゼロ以外の値を範囲の上限値に持ち上げ (切り上げ)、元の値に戻します。規模。

于 2012-06-23T13:12:34.613 に答える