連続変数をダミー変数に変換する方法

makedummiesの作者の荒様から,便利な使い方を教えていただきました

irisのSepal.Lengthを使用して、4~5, 5~6, 6~7, 7~8 の4区分をダミー変数にします

一瞬で終わります

library(dplyr)
library(makedummies)
data <- data.frame(iris$Sepal.Length)
summary(data)

4~8の間なので4以上5未満, 5以上6未満, 6以上7未満, 7以上8未満 の4区分でダミー変数を作成します

dat <- iris %>%
    mutate(
    dummy = cut(Sepal.Length, breaks = c(4,5,6,7,8), right = FALSE),
    dummy = factor(dummy, labels =c("4-5", "5-6", "6-7", "7-8"))) 
head(dat)

分かりにくいので1列,5列とdummy変数のみを残します

dat <- dat[,c(-2,-3,-4),]
head(dat)

このままダミー変数にしたら名義変数を全部ダミーにしてしまいます

なので、ダミー変数にしたくない名義変数はas.is = “”としておきます

基準を作りたくないとき(全部ダミー変数にしたいとき)には basal_level = T

dat <- makedummies(dat, basal_level = F, as.is = "Species")
head(dat)

4以上5未満が基準になっているので、変数としては出てきません

備忘録として、パイプを分解して解説入れておきます

dplyr::mutate データセットに新たに変数を追加する関数です

変数dummyを追加します

dat2 <- mutate(iris, dummy = cut(Sepal.Length, breaks = c(4,5,6,7,8), right = FALSE))
head(dat2)

カテゴリーなので数字じゃなくても良い

dat3 <- mutate(dat2, dummy = factor(dummy, labels =c("A", "B", "C", "D")))
head(dat3)

変数dummyをカテゴリー化

dat4 <- makedummies(dat3, basal_level = TRUE, as.is = "Species")
head(dat4)

基準の列を除いたダミー変数

dat4_2 <- makedummies(dat3, as.is = "Species")
head(dat4_2)

やっぱり便利なパッケージです

以前は以下のような方法でやってました

大変な作業でした

ここからは昔話です・・・

適当に150人分の年齢データを作成します
乱数で作成しているので、ファイルとして保存します
何度読み込んでも同じデータで練習できます

as.integer(runif(50 ,min =30 ,max=51))
as.integer(runif(50 ,min =40 ,max=80))
as.integer(runif(50 ,min =60 ,max=90))
age <- c(as.integer(runif(50 ,min =30 ,max=51)),
                    as.integer(runif(50 ,min =40 ,max=80)),
                    as.integer(runif(50 ,min =60 ,max=90)))
da <- data.frame(age)

CSVファイルにして作業ディレクトリに保存

write.csv(da, file="age.csv")  

保存したファイルを読み込み込んで作業を始めます

data_age <- read.csv("age.csv")

以下の3群のダミー変数を作成してみます
30~49歳
50~69歳
70~80歳

#30歳~50歳に該当する行のみTRUEとなる
a30 <- data_age$age <=49 
#30歳~50歳に1、他は0とするダミー変数を作成する
age_30c <- rep(1,length(data_age[a30,"age"])) 
age_50c <- rep(0,length(data_age[a30,"age"]))
age_70c <- rep(0,length(data_age[a30,"age"]))
#3列追加する 列名をage30d、age40d、age50dとする
a30_data <- transform(data_age[a30,],age30d=age_30c, 
                      age50d=age_50c,age70d=age_70c )

a50 <- data_age$age >=50 & data_age$age <=69
age_30c <- rep(0,length(data_age[a50,"age"]))
age_50c <- rep(1,length(data_age[a50,"age"]))
age_70c <- rep(0,length(data_age[a50,"age"]))
a50_data <- transform(data_age[a50,],age30d=age_30c, 
                      age50d=age_50c,age70d=age_70c )

a70 <- data_age$age >=70
age_30c <- rep(0,length(data_age[a70,"age"]))
age_50c <- rep(0,length(data_age[a70,"age"]))
age_70c <- rep(1,length(data_age[a70,"age"]))
a70_data <- transform(data_age[a70,],age30d=age_30c, 
                      age50d=age_50c,age70d=age_70c )

#ダミー変数が追加されたデータセットをdata_age_dとして作成

data_age_d <- rbind(a30_data, a50_data, a70_data)

完成したデータセットにイメージ

data_age_d[0:10,]

    X age age30d age50d age70d
1   1  32      1      0      0
2   2  39      1      0      0
3   3  43      1      0      0
4   4  34      1      0      0
5   5  32      1      0      0
6   6  46      1      0      0
7   7  43      1      0      0
8   8  35      1      0      0
9   9  34      1      0      0
10 10  35      1      0      0

さらに簡単に入力
30歳~49歳を対象としたサンプルを想定
30代をreferenceとして解釈したい場合は…
dataset=dat , 変数名=年齢

y <- dat
x <- dat$年齢

aa <- x<=39  #ここが基準になるので、全部0
a1 <- rep(0,length(y[aa, "年齢"])) 
AA <- transform(y[aa,], age30d=a1, age40d=a1, age50d = a1 )

bb <- x >=40 & x <=49
b1 <- rep(1,length(y[bb, "年齢"]))
b2 <- rep(0,length(y[bb, "年齢"]))
BB <- transform(y[bb,], age30d=b2, age40d=b1, age50d = b2 )

cc <- x >=50
c1 <- rep(1,length(y[cc, "年齢"]))
c2 <- rep(0,length(y[cc, "年齢"]))
CC <- transform(y[cc,], age30d=c2, age40d=c2, age50d = c1 )

data_age_d <- rbind(AA, BB, CC)

ダメ出し 間違い、分かりにくい部分などのご意見をお待ちします

タイトルとURLをコピーしました