5

私は現在苦労している非常に単純な質問があります。サンプルのデータフレームがある場合:

a <- c(1:5)  
b <- c(1,3,5,9,11)
df1 <- data.frame(a,b)

新しい列 ('c') を作成し、列 b に if ステートメントを使用して入力するにはどうすればよいですか。例: b の値が 1 または 2 の場合は「cat」 b の値が 3 ~ 5 の場合は「dog」 b の値が 6 より大きい場合は「rabbit」

したがって、データフレーム df1 を使用する列「c」は次のようになります: cat、dog、dog、rabbit、rabbit。

よろしくお願いします。

4

3 に答える 3

6
dfrm$dc <- c("dog", "cat", "rabbit")[ findInterval(dfrm$b, c(1, 2.5, 5.5, Inf)) ]

findInterval アプローチは、ネストされたifelse戦略よりもはるかに高速であり、ネストされていないステートメントをループする関数よりもはるかに高速であると推測していますif。より大きなデータを扱っている人は、効率の悪いアルゴリズムを選ぶと違いに気づきます。

これは実際には要求に対応していませんでしたが、R の新しいユーザーが問題に対する最も表現力豊かで効率的なアプローチを知っているとは限りません。「IF を使用してください」という要求は、2 つの主要なマクロ統計プロセッサ SPSS と SAS に典型的なコーディング手法を変換しようとする試みのように聞こえました。Rif制御構造は、最初の位置への引数が最初の要素に対してのみ評価されるため、通常、列を再コーディングするための効率的なアプローチではありません。それ自体では列を処理しませんが、ifelse関数はそれを行います。cut関数はここで (適切なパラメータbreaksとパラメータを使用して) 使用された可能性がありますが、文字値の代わりに値labelsが配信されたはずです。factorfindIntervalアプローチは、複数のレベルを返す機能のために選択されました (単一でifelseはできません)。ifelse約 2 ~ 3 レベルのネストの後、チェーンまたはネスト 's はすぐに見苦しく混乱するようになると思います。

于 2012-12-02T21:54:35.737 に答える
2
df1 <- 
    transform(
        df1 ,
        c =
            ifelse( b %in% 1:2 , 'cat' ,
            ifelse( b %in% 3:5 , 'dog' , 'rabbit' ) ) )
于 2012-12-02T19:27:34.537 に答える
2

ifelse() は便利ですが、直感的に期待できるものを提供しない場合があります。だから、私はそれを書くのが好きです。

a <- c(1:5)  
b <- c(1,3,5,9,11)
df1 <- data.frame(a,b)

species <- function(x) { 
if(x == 1 | x == 2) y <- "cat"
if(x > 2 & x < 6) y <- "dog"
if(x > 6) y <- "rabbit"
return(y)
}

df1$c <- sapply(df1$b,species)
于 2012-12-02T19:32:15.873 に答える