44

数式とデータ フレームがあり、model.matrix(). ただし、元のデータセットで見つかった NA を含めるには、結果のマトリックスが必要です。これを行うために使用する場合model.frame()は、単純に渡しますna.action=NULL。ただし、必要な出力は次のmodel.matrix()形式です。具体的には、右側の変数のみが必要であり、出力が (データ フレームではなく) 行列である必要があり、一連のダミー変数に変換される係数が必要です。

ループなどを使って何かを一緒にハックできると確信していますが、誰かがよりクリーンで効率的な回避策を提案できるかどうか疑問に思っていました. お時間をありがとうございました!

そして、ここに例があります:

dat <- data.frame(matrix(rnorm(20),5,4), gl(5,2))
dat[3,5] <- NA
names(dat) <- c(letters[1:4], 'fact')
ff <- a ~ b + fact

# This omits the row with a missing observation on the factor
model.matrix(ff, dat) 

# This keeps the NA, but it gives me a data frame and does not dichotomize the factor
model.frame(ff, dat, na.action=NULL) 

これが私が取得したいものです:

   (Intercept)          b fact2 fact3 fact4 fact5
1            1  0.7266086     0     0     0     0
2            1 -0.6088697     0     0     0     0
3            NA 0.4643360     NA    NA    NA    NA
4            1 -1.1666248     1     0     0     0
5            1 -0.7577394     0     1     0     0
6            1  0.7266086     0     1     0     0
7            1 -0.6088697     0     0     1     0
8            1  0.4643360     0     0     1     0
9            1 -1.1666248     0     0     0     1
10           1 -0.7577394     0     0     0     1
4

4 に答える 4

53

Joris の提案は機能しますが、これを行うためのより迅速でクリーンな方法は、グローバルな na.action 設定を使用することです。'Pass' オプションは、元のデータセットから NA を保持するという目標を達成します。

オプション 1: 合格

結果のマトリックスには、元のデータセットに対応する行に NA が含まれます。

options(na.action='na.pass')
model.matrix(ff, dat) 

オプション 2: 省略

結果のマトリックスは、NA を含む行をスキップします。

options(na.action='na.omit')
model.matrix(ff, dat) 

オプション 3: 失敗する

元のデータに NA が含まれていると、エラーが発生します。

options(na.action='na.fail')
model.matrix(ff, dat) 

もちろん、グローバル オプションを変更するときは、コードの他の部分の動作を変更する可能性があるため、常に注意してください。注意深い人は、元の設定を のようなもので保存current.na.action <- options('na.action')し、model.matrix を作成した後に元に戻すことがあります。

于 2013-10-23T14:30:00.220 に答える
38

もう 1 つの方法は、引数をmodel.frame持つ関数をna.action=na.passの 2 番目の引数として使用することmodel.matrixです。

> model.matrix(ff, model.frame(~ ., dat, na.action=na.pass))
   (Intercept)          b fact2 fact3 fact4 fact5
1            1 -1.3560754     0     0     0     0
2            1  2.5476965     0     0     0     0
3            1  0.4635628    NA    NA    NA    NA
4            1 -0.2871379     1     0     0     0
5            1  2.2684958     0     1     0     0
6            1 -1.3560754     0     1     0     0
7            1  2.5476965     0     0     1     0
8            1  0.4635628     0     0     1     0
9            1 -0.2871379     0     0     0     1
10           1  2.2684958     0     0     0     1

model.frameが呼び出されna.actionたときに維持される適切なアクションを設定できます。model.matrix

于 2015-08-11T19:04:33.520 に答える
16

model.matrixrownames に基づいて、オブジェクトを少しいじることができます。

MM <- model.matrix(ff,dat)
MM <- MM[match(rownames(dat),rownames(MM)),]
MM[,"b"] <- dat$b
rownames(MM) <- rownames(dat)

与える:

> MM
     (Intercept)         b fact2 fact3 fact4 fact5
1              1 0.9583010     0     0     0     0
2              1 0.3266986     0     0     0     0
3             NA 1.4992358    NA    NA    NA    NA
4              1 1.2867461     1     0     0     0
5              1 0.5024700     0     1     0     0
6              1 0.9583010     0     1     0     0
7              1 0.3266986     0     0     1     0
8              1 1.4992358     0     0     1     0
9              1 1.2867461     0     0     0     1
10             1 0.5024700     0     0     0     1

または、 を使用contrasts()して作業を行うこともできます。手で行列を構築すると、次のようになります。

cont <- contrasts(dat$fact)[as.numeric(dat$fact),]
colnames(cont) <- paste("fact",colnames(cont),sep="")
out <- cbind(1,dat$b,cont)
out[is.na(dat$fact),1] <- NA
colnames(out)[1:2]<- c("Intercept","b")
rownames(out) <- rownames(dat)

与える:

> out
     Intercept          b fact2 fact3 fact4 fact5
1            1  0.2534288     0     0     0     0
2            1  0.2697760     0     0     0     0
3           NA -0.8236879    NA    NA    NA    NA
4            1 -0.6053445     1     0     0     0
5            1  0.4608907     0     1     0     0
6            1  0.2534288     0     1     0     0
7            1  0.2697760     0     0     1     0
8            1 -0.8236879     0     0     1     0
9            1 -0.6053445     0     0     0     1
10           1  0.4608907     0     0     0     1

いずれにせよ、どちらの方法も、より複雑な式を処理できる関数に組み込むことができます。演習は読者に委ねます (論文でその文に出会ったとき、私は何を嫌いますか ;-) )

于 2011-04-11T08:20:01.720 に答える