以下に示すように、数値変数と因子変数で構成されるdata.frame
があります。
testFrame <- data.frame(First=sample(1:10, 20, replace=T),
Second=sample(1:20, 20, replace=T), Third=sample(1:10, 20, replace=T),
Fourth=rep(c("Alice","Bob","Charlie","David"), 5),
Fifth=rep(c("Edward","Frank","Georgia","Hank","Isaac"),4))
ダミー変数を因子に割り当て、数値変数のみを残すmatrix
を作成します。
model.matrix(~ First + Second + Third + Fourth + Fifth, data=testFrame)
予想どおりlm
を実行すると、各因子の1レベルが参照レベルとして除外されます。ただし、すべての要因のすべてのレベルに対して、ダミー/インジケータ変数を使用してmatrix
を作成します。私はglmnet
のためにこの行列を構築しているので、多重共線性については心配していません。
model.matrix
に要因のすべてのレベルのダミーを作成させる方法はありますか?
因子変数のcontrasts
をリセットする必要があります。
model.matrix(~ Fourth + Fifth, data=testFrame,
contrasts.arg=list(Fourth=contrasts(testFrame$Fourth, contrasts=F),
Fifth=contrasts(testFrame$Fifth, contrasts=F)))
または、入力を少し減らし、適切な名前なしで:
model.matrix(~ Fourth + Fifth, data=testFrame,
contrasts.arg=list(Fourth=diag(nlevels(testFrame$Fourth)),
Fifth=diag(nlevels(testFrame$Fifth))))
(自分で引き換えようとしています...)Jaredの@Fabiansの自動化に関する回答に対するコメントに対して、提供する必要があるのはコントラストマトリックスの名前付きリストだけです。 contrasts()
はベクトル/係数を取り、それからコントラスト行列を生成します。このため、lapply()
を使用して、データセット内の各要素に対してcontrasts()
を実行できます。提供されたtestFrame
の例の場合:
> lapply(testFrame[,4:5], contrasts, contrasts = FALSE)
$Fourth
Alice Bob Charlie David
Alice 1 0 0 0
Bob 0 1 0 0
Charlie 0 0 1 0
David 0 0 0 1
$Fifth
Edward Frank Georgia Hank Isaac
Edward 1 0 0 0 0
Frank 0 1 0 0 0
Georgia 0 0 1 0 0
Hank 0 0 0 1 0
Isaac 0 0 0 0 1
どのスロットが@fabiansにうまく答えていますか:
model.matrix(~ ., data=testFrame,
contrasts.arg = lapply(testFrame[,4:5], contrasts, contrasts=FALSE))
caret
は、ニース関数dummyVars
を実装して、2行でこれを実現します。
library(caret) dmy <- dummyVars(" ~ .", data = testFrame) testFrame2 <- data.frame(predict(dmy, newdata = testFrame))
最終列の確認:
colnames(testFrame2)
"First" "Second" "Third" "Fourth.Alice" "Fourth.Bob" "Fourth.Charlie" "Fourth.David" "Fifth.Edward" "Fifth.Frank" "Fifth.Georgia" "Fifth.Hank" "Fifth.Isaac"
ここで最も良い点は、元のデータフレームと、変換に使用された元の変数を除外したダミー変数を取得することです。
dummyVars
のcaret
も使用できます。 http://caret.r-forge.r-project.org/preprocess.html
Rパッケージ「CatEncoders」の使用
library(CatEncoders)
testFrame <- data.frame(First=sample(1:10, 20, replace=T),
Second=sample(1:20, 20, replace=T), Third=sample(1:10, 20, replace=T),
Fourth=rep(c("Alice","Bob","Charlie","David"), 5),
Fifth=rep(c("Edward","Frank","Georgia","Hank","Isaac"),4))
fit <- OneHotEncoder.fit(testFrame)
z <- transform(fit,testFrame,sparse=TRUE) # give the sparse output
z <- transform(fit,testFrame,sparse=FALSE) # give the dense output
OK。上記を読んで、まとめてください。マトリックスが必要だとします。係数ベクトルを乗算して線形予測子を取得する「X.factors」。まだいくつかの追加手順があります:
X.factors =
model.matrix( ~ ., data=X, contrasts.arg =
lapply(data.frame(X[,sapply(data.frame(X), is.factor)]),
contrasts, contrasts = FALSE))
(ファクター列が1つしかない場合は、X [*]をデータフレームに戻す必要があることに注意してください。)
次に、次のようになったと言います。
attr(X.factors,"assign")
[1] 0 1 **2** 2 **3** 3 3 **4** 4 4 5 6 7 8 9 10 #emphasis added
各要素の** 'd参照レベルを取り除きたい
att = attr(X.factors,"assign")
factor.columns = unique(att[duplicated(att)])
unwanted.columns = match(factor.columns,att)
X.factors = X.factors[,-unwanted.columns]
X.factors = (data.matrix(X.factors))
model.matrix(~ First + Second + Third + Fourth + Fifth - 1, data=testFrame)
または
model.matrix(~ First + Second + Third + Fourth + Fifth + 0, data=testFrame)
最も簡単なはずです
stats
パッケージの回答:
new_tr <- model.matrix(~.+0,data = testFrame)
Rのモデル式(たとえば、lm())に+0(または-1)を追加すると、切片が抑制されます。
tidyverse
回答:
library(dplyr)
library(tidyr)
result <- testFrame %>%
mutate(one = 1) %>% spread(Fourth, one, fill = 0, sep = "") %>%
mutate(one = 1) %>% spread(Fifth, one, fill = 0, sep = "")
望ましい結果が得られます(@Gavin Simpsonの答えと同じ):
> head(result, 6)
First Second Third FourthAlice FourthBob FourthCharlie FourthDavid FifthEdward FifthFrank FifthGeorgia FifthHank FifthIsaac
1 1 5 4 0 0 1 0 0 1 0 0 0
2 1 14 10 0 0 0 1 0 0 1 0 0
3 2 2 9 0 1 0 0 1 0 0 0 0
4 2 5 4 0 0 0 1 0 1 0 0 0
5 2 13 5 0 0 1 0 1 0 0 0 0
6 2 15 7 1 0 0 0 1 0 0 0 0