library(tidyverse)
library(readxl)
library(vcdExtra)
library(gt)
library(FactoMineR)
library(showtext)
showtext_auto(TRUE)
library(explor)
本稿は、SSJDA(Nesstar)でリモート集計されたクロス表から「個票」の形式を復元する方法のその2、多元表を複数変数の「個票」に復元する方法について記述する。
クロス表を個票に復元する手順は以下のようになる。
集計されたクロス表をなんらかの方法で、度数表(Freq form)に変換する。その度数表を、vcdExtra::expand.dft() を用いて各行をそのFreqに示されている数だけ復元する。こうして、個票(case form)は復元される。
その1では、2元クロス表を個票(case form)に変換(復元)する方法について確認し、記述した。その際に、クロス表を度数表に変換する方法を確認したが、本稿(その2)では、その方法を用いて、多元クロス表を複数変数の「個票」に変換する。
.text <- "年齢 そう思う どちらかといえばそう思う どちらかといえばそう思わない そう思わない DKNA"
stringr::str_split(.text,pattern = "\t") %>% unlist() ->cnames
"年齢 そう思う どちら_そう思う どちら_そう思わない そう思わない DKNA" %>% stringr::str_split(pattern = "\t") %>% unlist() -> cnames2
.text2 <- "20代,30代,40代,50代,60代"
stringr::str_split(.text2,pattern = ",") %>% unlist() ->rnames
.dtext <- "20,63,77,151,14,28,131,126,204,27,27,147,158,212,18,50,166,165,279,24,121,220,151,211,37"
stringr::str_split(.dtext,pattern = ",") %>% unlist() ->.ddd
matrix(as.numeric(.ddd),5,5,byrow=TRUE) -> .d
colnames(.d) <- cnames[-1]
rownames(.d) <- rnames
#.d %>% gt()
.d %>% knitr::kable()
.d -> .d0
リモート集計によるクロス表
リモート集計による、性別、年齢、Q16a、Q16cの多重クロス表
.dname <- read_excel("SSM2005-Q16multi.xls",skip=3,n_max = 1)
## New names:
## • `` -> `...2`
## • `` -> `...3`
names(.dname) %>% .[4:8] -> lnames
.dm <- read_excel("SSM2005-Q16multi.xls",skip=4)
## New names:
## • `` -> `...4`
## • `` -> `...5`
## • `` -> `...6`
## • `` -> `...7`
## • `` -> `...8`
## • `` -> `...9`
names(.dm)[4:8] <- names(.dname) %>% .[4:8]
.dm %>% rename(性別="問1(1)性 別",Q16a=names(.dm)[2],年齢=names(.dm)[3]) %>% fill("性別") %>% fill(Q16a) %>% select(-"...9") %>% filter(性別!="N=") %>%
pivot_longer(names_to = "Q16c",values_to = "Freq",cols=-c(年齢,性別,Q16a)) %>% expand.dft() %>%
mutate(Q16af=factor(Q16a,levels=lnames),Q16cf=factor(Q16c,levels=lnames)) %>% select(性別,年齢,Q16af,Q16cf)-> .tblq16
.tblq16 %>% summary()
## 性別 年齢 Q16af
## Length:2827 Min. :20.00 そう思う : 246
## Class :character 1st Qu.:37.00 どちらかといえばそう思う : 727
## Mode :character Median :50.00 どちらかといえばそう思わない: 677
## Mean :48.17 そう思わない :1057
## 3rd Qu.:60.00 DKNA : 120
## Max. :70.00
## Q16cf
## そう思う : 572
## どちらかといえばそう思う :1141
## どちらかといえばそう思わない: 418
## そう思わない : 545
## DKNA : 151
##
.tblq16 %>% count(Q16af,Q16cf) %>% pivot_wider(names_from = Q16cf,values_from = n) %>% knitr::kable()
| Q16af | そう思う | どちらかといえばそう思う | どちらかといえばそう思わない | そう思わない | DKNA |
|---|---|---|---|---|---|
| そう思う | 172 | 44 | 8 | 17 | 5 |
| どちらかといえばそう思う | 180 | 441 | 64 | 31 | 11 |
| どちらかといえばそう思わない | 79 | 316 | 199 | 66 | 17 |
| そう思わない | 132 | 319 | 139 | 427 | 40 |
| DKNA | 9 | 21 | 8 | 4 | 78 |
.tblq16 %>% filter(性別=="男性") %>% count(Q16af,Q16cf) %>% pivot_wider(names_from = "Q16cf",values_from = "n") %>% write_excel_csv("male.csv")
#knitr::kable(caption = "男性")
.tblq16 %>% filter(性別=="女性") %>% count(Q16af,Q16cf) %>% pivot_wider(names_from = "Q16cf",values_from = "n") %>% write_excel_csv("female.csv")
#knitr::kable(caption = "女性")
.tblq16 %>% mutate(年齢f= factor(年齢)) %>% select(-年齢) %>% filter(Q16af!="DKNA") %>% filter(Q16cf!="DKNA") -> .tblq16f
res.MCA <- MCA(.tblq16f,quali.sup = c(1,4))
#explor(res.MCA)
これでは年齢がごちゃごちゃでわからないので、年齢を10歳刻みに変換。そして、年齢10歳刻み+性別のinteractive coding を行う。
.tblq16 %>% mutate(Age10=as.integer(as.numeric(`年齢`)/10)*10) %>% mutate(Age10性別= str_c("A",Age10,性別)) %>%
select(-年齢,-Age10) %>% filter(Q16af!="DKNA") %>% filter(Q16cf!="DKNA") -> .tblq16Age10
res.MCA2 <- MCA(.tblq16Age10,quali.sup = c(1,4))
## Warning: ggrepel: 9 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
#explor(res.MCA2)