배경 및 목적

서울시 2001~2015년도의 출생아 체중 정보를 이용해서 연도/성별/체중 비중을 그래프로 비교해본다.

주요 전처리:

TODO:

자료출처:

자료 조회

# 필요한 패키지를 로딩한다.
library(plyr) # XXX: plyr, dplyr 로딩 순서가 다르니까 데이터 연산 시 이상한 오류가 발생한다.
library(dplyr)
library(tidyr) # gather() 함수 사용
library(ggplot2)
df_data <- read.table('./170812-Octagon.txt', header=T, sep="\t", as.is = T, strip.white = T)

# 컬럼 이름을 변경한다.
names(df_data) <- c('year', 'sex', 'total', 'w1.4', 'w1.9', 'w2.4', 'w2.9', 'w3.4', 'w3.9', 'w4.4', 'w4.4over', 'nodata', 'avg')

str(df_data)
## 'data.frame':    45 obs. of  13 variables:
##  $ year    : int  2001 2001 2001 2002 2002 2002 2003 2003 2003 2004 ...
##  $ sex     : chr  "계" "남자" "여자" "계" ...
##  $ total   : chr  "113,632 " "58,888 " "54,744 " "100,928 " ...
##  $ w1.4    : chr  "399 " "194 " "205 " "336 " ...
##  $ w1.9    : chr  "762 " "381 " "381 " "742 " ...
##  $ w2.4    : chr  "3,165 " "1,492 " "1,673 " "2,801 " ...
##  $ w2.9    : chr  "20,543 " "8,948 " "11,595 " "17,913 " ...
##  $ w3.4    : chr  "52,365 " "26,340 " "26,025 " "46,242 " ...
##  $ w3.9    : chr  "29,885 " "17,444 " "12,441 " "26,601 " ...
##  $ w4.4    : chr  "5,630 " "3,550 " "2,080 " "4,974 " ...
##  $ w4.4over: chr  "597 " "397 " "200 " "560 " ...
##  $ nodata  : chr  "286 " "142 " "144 " "759 " ...
##  $ avg     : chr  "3.27 " "3.32 " "3.22 " "3.27 " ...

자료 cleansing

# 남자, 여자 데이터만 취합한다.
df_data.1 <- df_data[df_data$sex %in% c('남자', '여자'),]
# 필요한 컬럼만 취합한다.
df_data.1 <- df_data.1 %>% select(c(year, sex, w1.4, w1.9, w2.4, w2.9, w3.4, w3.9, w4.4, w4.4over, nodata))

## 긴 데이터 포맷으로 변경한다.
df_data.2 <- gather(df_data.1, weight_category, cnt, -c(year, sex))
# 범주 데이터 및 숫자 데이터로 변환한다.
df_data.2$year <- as.factor(df_data.2$year)
df_data.2$sex <- as.factor(df_data.2$sex)
df_data.2$weight_category <- as.factor(df_data.2$weight_category)
# 숫자 뒤에 이상한 공백이 있는데 일반적인 gsub()로 공백이 제거되지 않는다.
df_data.2$cnt <- gsub(",", "", df_data.2$cnt)
df_data.2$cnt <- as.numeric(gsub("([0-9]+).*$", "\\1", df_data.2$cnt)) # XXX: 문자열에서 숫자를 분리한다.

남자, 여자의 출생 총수를 연도별로 비교한다.

# tapply(df_data.2$cnt, list(df_data.2$year, df_data.2$sex), sum) 연산으로도 연도 및 성별에 따른 전체 합계를 구할 수 있지만, wide 형태의 데이터가 조회된다.
# group_by, summarise는 long 형태의 데이터가 조회된다.
t <- df_data.2 %>% group_by(year, sex) %>% summarise(total = sum(cnt))

g <- ggplot(t, aes(x = year, y = total, color=sex, group=sex)) + geom_line()
g <- g + ylim(0, 60000)
g

이제 여자 성별의 무게별 비중의 차이가 연도별로 달라지는지 알아본다.

# XXX: 그룹별 비율 구하기 - 방법1
#df_data.2$total <- 0
# data.frame내의 다중 검색 조건의 and 연산자는 && 이다. &, && 차이를 확실히 알아야겠다.
# df_data.2$total <- df_data.2$cnt / t[t$year == df_data.2$year && t$sex == df_data.2$sex,]$total

# XXX: 그룹별 비율 구하기 - 방법2
#df_data.2 <- df_data.2 %>% group_by(year, sex) %>% mutate(total3 = sum(cnt))
#df_data.2 <- df_data.2 %>% mutate(total4 = cnt / total3)

# XXX: 그룹별 비율 구하기 - 방법3
df_data.2 <- ddply(df_data.2, .(year, sex), transform, total = cnt / sum(cnt))


g <- ggplot(df_data.2[df_data.2$sex == '여자',], aes(x = year, y = total, color=weight_category, group=weight_category)) + geom_line()
g <- g + ylim(0, 0.5)
g <- g + geom_point(size=2)
g <- g + annotate("rect", xmin='2004', xmax='2005', ymin=0, ymax=0.5, alpha = .1, fill = "blue")
g

여자 아이의 몸무게는 2004년도를 기점으로 2.9~3.4Kg 사이는 증가하고 있고, 3.9~4.4Kg 사이의 몸무게는 감소하고 있다.

(To be continued)