理学療法士がまとめたノート

統計学備忘録 since2016

Rを使って統計学を勉強するブログです

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

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)

 iris.Sepal.Length
 Min.   :4.300    
 1st Qu.:5.100    
 Median :5.800    
 Mean   :5.843    
 3rd Qu.:6.400    
 Max.   :7.900  
# 4~8の間なので4以上5未満, 5以上6未満, 6以上7未満, 7以上8未満 の4区分でダミー変数を作成します

res <- iris %>%
  mutate(dummy = cut(Sepal.Length, breaks = c(4,5,6,7,8), right = FALSE),
         dummy = factor(dummy, labels =c("4", "5", "6", "7"))) %>%
  makedummies(basal_level = TRUE, as.is = "Species")
head(res)

#一瞬で完成

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species dummy_4 dummy_5 dummy_6 dummy_7
1          5.1         3.5          1.4         0.2  setosa       0       1       0       0
2          4.9         3.0          1.4         0.2  setosa       1       0       0       0
3          4.7         3.2          1.3         0.2  setosa       1       0       0       0
4          4.6         3.1          1.5         0.2  setosa       1       0       0       0
5          5.0         3.6          1.4         0.2  setosa       0       1       0       0
6          5.4         3.9          1.7         0.4  setosa       0       1       0       0

ここからは個人的な学習用です
備忘録として、パイプを分解して解説入れておきます

# dplyr::mutate データセットに新たに変数を追加する関数です
#変数dummyを追加します
dat2 <- mutate(iris, dummy = cut(Sepal.Length, breaks = c(4,5,6,7,8), right = FALSE))
head(dat2)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species dummy
1          5.1         3.5          1.4         0.2  setosa [5,6)
2          4.9         3.0          1.4         0.2  setosa [4,5)
3          4.7         3.2          1.3         0.2  setosa [4,5)
4          4.6         3.1          1.5         0.2  setosa [4,5)
5          5.0         3.6          1.4         0.2  setosa [5,6)
6          5.4         3.9          1.7         0.4  setosa [5,6)

dat3 <- mutate(dat2, dummy = factor(dummy, labels =c("A", "B", "C", "D")))
#カテゴリーなので数字じゃなくても良い
head(dat3)
# 変数dummyをカテゴリー化
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species dummy
1          5.1         3.5          1.4         0.2  setosa     B
2          4.9         3.0          1.4         0.2  setosa     A
3          4.7         3.2          1.3         0.2  setosa     A
4          4.6         3.1          1.5         0.2  setosa     A
5          5.0         3.6          1.4         0.2  setosa     B
6          5.4         3.9          1.7         0.4  setosa     B

# ダミー変数
dat4 <- makedummies(dat3, basal_level = TRUE, as.is = "Species")
head(dat4)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species dummy_A dummy_B dummy_C dummy_D
1          5.1         3.5          1.4         0.2  setosa       0       1       0       0
2          4.9         3.0          1.4         0.2  setosa       1       0       0       0
3          4.7         3.2          1.3         0.2  setosa       1       0       0       0
4          4.6         3.1          1.5         0.2  setosa       1       0       0       0
5          5.0         3.6          1.4         0.2  setosa       0       1       0       0
6          5.4         3.9          1.7         0.4  setosa       0       1       0       0

# 基準の列を除いたダミー変数
dat4_2 <- makedummies(dat3, as.is = "Species")
head(dat4_2)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species dummy_B dummy_C dummy_D
1          5.1         3.5          1.4         0.2  setosa       1       0       0
2          4.9         3.0          1.4         0.2  setosa       0       0       0
3          4.7         3.2          1.3         0.2  setosa       0       0       0
4          4.6         3.1          1.5         0.2  setosa       0       0       0
5          5.0         3.6          1.4         0.2  setosa       1       0       0
6          5.4         3.9          1.7         0.4  setosa       1       0       0

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

ここからは、以前の記事です
大変な作業でした。

適当に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)