- 범주형 변수와 짝꿍인 표를 생성하는 작업흐름을 이해한다.
- 표를 생성하는 3가지 자료구조를 이해한다.
- 표를 생성하고, 표현하고, 시각화 과정을 실습한다.
데이터를 표로 생성하는 것은 상황에 따라서 별것 아니기도 하지만, 매우 복잡한 작업이 되기도 한다. 종국에는 데이터를 계수하는 것으로 종결된다. 하지만, 2차원 이상일 경우, R로 표현되는 데이터 자료형이 다양하고, 기술적으로도 추상화 개념을 도입할 필요가 있다. 따라서, 데이터를 요구되는 표로 나타내고 처리하는데 경우에 따라서 매우 많은 함수를 취사선택하게 된다.
범주형 데이터분석은 표를 작성하면서 시작한다고 해도 과언은 아니다. R에는 2차원 혹은 다차원 표를 가지고 작업하는데 필요한 도구가 상당히 많이 존재하지만 완벽하지는 않는다. DescTools
팩키지에는 실무적인 측면에서 이런 간극을 매울 수 있는 도구를 일부 제공한다.
표를 작성하는데 있어 가장 먼저 확인해야 되는 사항은 범주형 자료구조를 확인하는데 있다.
data.frame
혹은 행렬에 원자료에 각행에 사례 한가지만 기록되어 저장되어 있는 경우.Untable()
함수는 데이터프레임을 입력받아 관측점 하나에 빈도수 하나인 데이터프레임으로 변환시킨다.
Admit Gender Dept
1 Admitted Male A
2 Admitted Male A
3 Admitted Male A
4 Admitted Male A
5 Admitted Male A
6 Admitted Male A
각 요인별 조합을 유일무이한 값으로 계수하여 각 행에 저장함. 흔히 가중치(weights)라고도 하고, Freq
칼럼이 이에 해당함.
Admit Gender Dept Freq
1 Admitted Male A 512
2 Rejected Male A 313
3 Admitted Female A 89
4 Rejected Female A 19
5 Admitted Male B 353
6 Rejected Male B 207
다차원 표, 배열, 행렬이 이에 해당.
, , Dept = A
Gender
Admit Male Female
Admitted 512 89
Rejected 313 19
, , Dept = B
Gender
Admit Male Female
Admitted 353 17
Rejected 207 8
세가지 범주형 데이터 표현방식은 각기 다른 사용도와 의미가 내포되어 있다. 예를 들어 2번 표현은 1번 표현보다 훨씬 적은 저장공간을 차지하게 되고, 1번 표현방식은 즉각적으로 데이터를 표로 작성하는데 용이하다.
일반적으로 범주형 데이터를 구성하는데 사용되는 표 자료구조(tabel data structure)를 상호 비교해보자.
단일 관측점(Single case)
Admit Gender Dept
1 Admitted Male A
2 Admitted Male A
3 Admitted Male A
4 Admitted Male A
5 Admitted Male A
6 Admitted Male A
빈도수(Frequency)
Admit Gender Dept Freq
1 Admitted Male A 512
2 Rejected Male A 313
3 Admitted Female A 89
4 Rejected Female A 19
5 Admitted Male B 353
6 Rejected Male B 207
표(table)
, , Dept = A
Gender
Admit Male Female
Admitted 512 89
Rejected 313 19
, , Dept = B
Gender
Admit Male Female
Admitted 353 17
Rejected 207 8
표데이터를 다음과 같이 Case-by-Case
, 빈도수 가중치
, 표
세가지 자료형이 존재한다.
d_col <- Untable(HairEyeColor)
d.weight <- as.data.frame(HairEyeColor)
tab <- HairEyeColor
사례별(Case-by-Case)
→ 빈도수(Frequency)
: as.data.frame(table(d_col))
사례별(Case-by-Case)
→ 표(Table) → 빈도수(Frequency)
변환시킴빈도수(Frequency)
→ 사례별(Case-by-Case)
: Untable(d.weight)
library(DescTools)
팩키지 Untable()
함수 사용사례별(Case-by-Case)
→ 표(Table)
: table(d_col)
표(Table)
→ 사례별(Case-by-Case)
: Untable(tab)
빈도수(Frequency)
→ 표(Table)
: xtabs(Freq ~ ., d.weight)
표(Table)
→ 빈도수(Frequency)
: as.data.frame(tab)
분할표(Contingency Table) 데이터를 R에 입력하는 방법은 다수 있다. 다음 표는 Agresti (2007) p.39, 정당과 성별를 표로 작성한 교차표다. 이를 R 데이터로 저장한다.
Party | ||||
---|---|---|---|---|
Democrat | Independent | Republican | ||
Gender | M | 762 | 327 | 468 |
F | 484 | 239 | 477 |
TextToTable()
함수 활용 : DescTools
팩키지에서 지원되는 함수를 사용한다.txt <- "
Democrat, Independent, Republican
M, 762, 327, 468
F, 484, 239, 477"
TextToTable(txt, sep=",", dimnames=c("gender", "party"))
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
as.table()
함수와 rbind()
함수 사용rbind()
함수와 as.table()
함수를 사용해서 입력 데이터를 table
자료형으로 변환시키고 나서, dimnames()
함수로 표에 사용되는 라벨을 부여하여 분할표를 완성시킨다.
tab <- as.table(rbind(c(762, 327, 468), c(484, 239, 477)))
dimnames(tab) <- list(gender = c("M", "F"),
party = c("Democrat", "Independent", "Republican"))
tab
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
matrix()
함수를 사용matrix()
함수를 사용하여 동일하게 표를 구성할 수도 있다. 이 경우 byrow=TRUE
로 설정해서 행렬이 행으로 쌓이게 한다.
as.table(matrix(c(762, 327, 468, 484, 239, 477), nrow=2, byrow=TRUE,
dimnames=list(gender= c("M", "F"),
party = c("Democrat", "Independent", "Republican"))))
party
gender Democrat Independent Republican
M 762 327 468
F 484 239 477
다차원 표, 예를 들어 \(2 \times 2 \times 2\) 표를 생성할 경우 배열을 사용한다. 이럴 경우 첫번째 차원은 행, 두번째 차원은 열, 세번째 차원은 깊이 순으로 저장된다.
salary <- array(
c(38, 12, 102, 141, 12, 9, 136, 383),
dim=c(2, 2, 2),
dimnames=list(exposure = c("exposed", "not"),
disease = c("case", "control"),
salary = c("<1000", ">=1000"))
)
read.ftable()
함수를 사용해서 고차원 표를 텍스트 파일로 표현된 정보를 표로 표현할 수도 있다.
txt <-
" Sex Male Female
Eye Brown Blue Hazel Green Brown Blue Hazel Green
Hair
Black 32 11 10 3 36 9 5 2
Brown 53 50 25 15 66 34 29 14
Red 10 10 7 7 16 7 7 7
Blond 3 30 5 8 4 64 5 8
"
tab <- as.table(read.ftable(textConnection(txt)))
DescTools
팩키지의 Freq()
함수를 활용해서 숫자형 변수를 범주형으로 표현하기 수월하다. Freq()
함수는 hist()
함수의 기본설정을 그대로 사용하여 숫자형 변수를 범주형으로 변경시킨다.
level freq perc cumfreq cumperc
1 [15,20] 3 0.3% 3 0.3%
2 (20,25] 30 2.6% 33 2.8%
3 (25,30] 58 5.0% 91 7.8%
4 (30,35] 48 4.1% 139 11.9%
5 (35,40] 100 8.5% 239 20.4%
6 (40,45] 130 11.1% 369 31.5%
7 (45,50] 219 18.7% 588 50.3%
8 (50,55] 268 22.9% 856 73.2%
9 (55,60] 241 20.6% 1'097 93.8%
10 (60,65] 73 6.2% 1'170 100.0%
expand
기능 활용빈도수가 크지 않는 표를 작성하는 경우 expand.grid()
함수를 활용하여 빈도수를 입력하는 것이 여러모로 편리하다. 요인을 expand.grid() 함수로 처리하고, 벡터로 빈도수를 c()
함수로 작성한다. expand.grid()
함수로 요인사이 가능한 모든 조합을 표현하고, count
변수로 조합하여 데이터프레임으로 생성시킨다. 그리고 나서 xtabs
함수를 사용해서 표로 변환시킨다.
tab <- data.frame(expand.grid(
Hair = c("Black", "Brown", "Red", "Blond"),
Eye = c("Brown", "Blue", "Hazel", "Green"),
Sex = c("Male", "Female")),
count = c(32,53,10,3,11,50,10,30,10,25,7,5,3,15,7,8,
36,66,16,4,9,34,7,64,5,29,7,5,2,14,7,8) )
tab %>% head
Hair Eye Sex count
1 Black Brown Male 32
2 Brown Brown Male 53
3 Red Brown Male 10
4 Blond Brown Male 3
5 Black Blue Male 11
6 Brown Blue Male 50
DescTools
팩키지에 포함된 HairEyeColor
객체는 table
자료형을 갖고 있다. 이를 Untable
명령어를 통해 한 행에 빈도수 하나만 갖는 데이터로 변환을 시킨다. 그리고 이를 바탕으로 다양한 표를 생성시켜 보자.
Hair Eye Sex
1 Blond Brown Male
2 Blond Brown Male
3 Blond Brown Male
요인형 자료를 갖고 표를 생성시키는 방법은 table
함수로 빈도수, prop.table
함수로 백분율을 표로 표현한다.
Black Brown Red Blond
108 286 71 127
Black Brown Red Blond
0.1824324 0.4831081 0.1199324 0.2145270
Freq
함수를 사용해서 단변량 범주형 변수의 경우 빈도수와 백분율을 간단히 표로 표현한다.
level freq perc cumfreq cumperc
1 Brown 286 48.3% 286 48.3%
2 Blond 127 21.5% 413 69.8%
3 Black 108 18.2% 521 88.0%
4 Red 71 12.0% 592 100.0%
이변량 범주형 변수를 표로 표현하는 전통적인 방식은 table
과 prop.table
함수를 사용하는 것은 동일하다. 하지만, 행 백분율/열 백분율/전체 백분율을 표현하여야 하기 때문에 margin=
인수를 넣어 제어한다.
margin=1
: 행 백분율margin=2
: 열 백분율margin=NULL
: 전체 백분율 Sex
Hair Male Female
Black 56 52
Brown 143 143
Red 34 37
Blond 46 81
혹은 plyr
, dplyr
팩키지의 count()
함수를 사용하면 table
, as.data.frame
단계를 거치지 않고 일관된 방식으로 표생성에 필요한 데이터를 만들어 낼 수 있다. 이를 xtabs
함수와 결합하여 표
Sex
Hair Male Female
Black 56 52
Brown 143 143
Red 34 37
Blond 46 81
Eye
Hair Brown Blue Hazel Green
Black 0.62962963 0.18518519 0.13888889 0.04629630
Brown 0.41608392 0.29370629 0.18881119 0.10139860
Red 0.36619718 0.23943662 0.19718310 0.19718310
Blond 0.05511811 0.74015748 0.07874016 0.12598425
Eye
Hair Brown Blue Hazel Green
Black 0.30909091 0.09302326 0.16129032 0.07812500
Brown 0.54090909 0.39069767 0.58064516 0.45312500
Red 0.11818182 0.07906977 0.15053763 0.21875000
Blond 0.03181818 0.43720930 0.10752688 0.25000000
Eye
Hair Brown Blue Hazel Green
Black 0.114864865 0.033783784 0.025337838 0.008445946
Brown 0.201013514 0.141891892 0.091216216 0.048986486
Red 0.043918919 0.028716216 0.023648649 0.023648649
Blond 0.011824324 0.158783784 0.016891892 0.027027027
PercTable()
함수를 rfrq=
인자를 상대빈도수를 제어한다. 011
은 행과 열 백분율만 출력한다.
Eye Brown Blue Hazel Green Sum
Hair
Black freq 68 20 15 5 108
perc 11.5% 3.4% 2.5% 0.8% 18.2%
p.row 63.0% 18.5% 13.9% 4.6% .
p.col 30.9% 9.3% 16.1% 7.8% .
Brown freq 119 84 54 29 286
perc 20.1% 14.2% 9.1% 4.9% 48.3%
p.row 41.6% 29.4% 18.9% 10.1% .
p.col 54.1% 39.1% 58.1% 45.3% .
Red freq 26 17 14 14 71
perc 4.4% 2.9% 2.4% 2.4% 12.0%
p.row 36.6% 23.9% 19.7% 19.7% .
p.col 11.8% 7.9% 15.1% 21.9% .
Blond freq 7 94 10 16 127
perc 1.2% 15.9% 1.7% 2.7% 21.5%
p.row 5.5% 74.0% 7.9% 12.6% .
p.col 3.2% 43.7% 10.8% 25.0% .
Sum freq 220 215 93 64 592
perc 37.2% 36.3% 15.7% 10.8% 100.0%
p.row . . . . .
p.col . . . . .
Margins(HairEyeColor, ord="desc")
명령어처럼 Margins()
함수가 있어 표 자료형을 입력받아 각 표차원별로 표를 신속하게 생성할 수 있다.
mosaicplot()
모자이크 그래프를 사용하여 범주형 데이터를 시각화 한다. 먼저 데이터를 준비하고 색상을 정의한다. 그리고 나서 PlotMosaic()
함수를 호출하여 도식화한다.
tab <- as.table(apply(HairEyeColor, c(1,2), sum))
tab <- tab[,c("Brown","Hazel","Green","Blue")]
cols <- SetAlpha(c("sienna4", "burlywood", "chartreuse3", "slategray1"), 0.6)
PlotMosaic(tab, col=cols, main = "Hair ~ Eye")
Eye Brown Hazel Green Blue
Hair
Black 63.0% 13.9% 4.6% 18.5%
Brown 41.6% 18.9% 10.1% 29.4%
Red 36.6% 19.7% 19.7% 23.9%
Blond 5.5% 7.9% 12.6% 74.0%
Hair
Black Brown Red Blond
0.1824324 0.4831081 0.1199324 0.2145270
horiz = FALSE
인자를 넘겨 행과 열을 바꿔 모자이크 그래프로 도식화도 가능하다.
cols <- SetAlpha(c("moccasin", "salmon1", "wheat3", "gray32"), 0.8)
PlotMosaic(tab, col=cols, main = "Hair ~ Eye", horiz = FALSE)
Eye Brown Hazel Green Blue
Hair
Black 30.9% 16.1% 7.8% 9.3%
Brown 54.1% 58.1% 45.3% 39.1%
Red 11.8% 15.1% 21.9% 7.9%
Blond 3.2% 10.8% 25.0% 43.7%
Eye
Brown Hazel Green Blue
0.3716216 0.1570946 0.1081081 0.3631757
PlotCirc()
함수를 통해 두 변수의 각 수준별 관련성을 도식화하는 것도 가능하다.
formattable
formattable
: Formattable Data Structures 팩키지를 사용하여 표를 꾸밀 수 있다.
library(formattable)
data.frame(UCBAdmissions) %>%
select(Dept, Gender, Freq, Admit) %>%
mutate(Admit = ifelse(Admit == "Admitted", TRUE, FALSE)) %>%
formattable(., list(
Gender = formatter("span", style = x ~ ifelse(x == "Male",
style(color = "green", font.weight = "bold"), NA)),
area(col = c(Freq)) ~ normalize_bar("pink", 0.2),
Admit = formatter("span",
style = x ~ style(color = ifelse(x, "green", "red")),
x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Admitted", "Rejected")))
))
Dept | Gender | Freq | Admit |
---|---|---|---|
A | Male | 512 | Admitted |
A | Male | 313 | Rejected |
A | Female | 89 | Admitted |
A | Female | 19 | Rejected |
B | Male | 353 | Admitted |
B | Male | 207 | Rejected |
B | Female | 17 | Admitted |
B | Female | 8 | Rejected |
C | Male | 120 | Admitted |
C | Male | 205 | Rejected |
C | Female | 202 | Admitted |
C | Female | 391 | Rejected |
D | Male | 138 | Admitted |
D | Male | 279 | Rejected |
D | Female | 131 | Admitted |
D | Female | 244 | Rejected |
E | Male | 53 | Admitted |
E | Male | 138 | Rejected |
E | Female | 94 | Admitted |
E | Female | 299 | Rejected |
F | Male | 22 | Admitted |
F | Male | 351 | Rejected |
F | Female | 24 | Admitted |
F | Female | 317 | Rejected |
gt
2 3gt
팩키지는 표(table)을 각 부분으로 나눠서 티블(tibble)
혹은 데이터프레임(data frame)
객체를 gt
객체로 변환시킨 후에 gt
표(테이블)로 만들어서 각종 문서에 사용할 수 있다.
먼저 gt
테이블 구성요소를 다음과 같이 구성할 수 있고, 이를 gt
작업흐름에 맞춰 작업한다. 즉 표는 다음을 구성요소로 갖는다.
일반적인 gt
테이블 작업흐름은 앞서 언급한 것처럼 tibble
혹은 data.frame
→ gt
객체 → gt
테이블이 된다.
UCBAdmissions
데이터셋을 가지고 gt
테이블을 제작해 보자.
# remotes::install_github("rstudio/gt")
library(gt)
data.frame(UCBAdmissions) %>%
select(Dept, Gender, Freq, Admit) %>%
head() %>%
gt() %>%
tab_header(
title = "미국 버클리 대학 입학",
subtitle = "학과별, 성별, 입학 여부")
미국 버클리 대학 입학 | |||
---|---|---|---|
학과별, 성별, 입학 여부 | |||
Dept | Gender | Freq | Admit |
A | Male | 512 | Admitted |
A | Male | 313 | Rejected |
A | Female | 89 | Admitted |
A | Female | 19 | Rejected |
B | Male | 353 | Admitted |
B | Male | 207 | Rejected |