쭈쌤
쭈쌤 Hello World

[R 데이터 분석,시각화] 한국복지패널 데이터 분석 실습

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[R 데이터 분석,시각화] 한국복지패널 데이터 분석 실습≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[R 데이터 분석,시각화] 한국복지패널 데이터 분석 실습

한국복지패널은 빈곤층, 근로빈곤층, 차상위층등 다양한 계층의 규모 및 생활실태 변화를 동태적으로 파악함으로써 정책형성에 기여함과 동시에 정책지원에 따른 효과성을 제고하고자 하는 곳으로서 한국복지패널의 자료실에서 수집된 데이터들을 내려받아 볼 수 있습니다.

이 포스팅에서는 한국복지패널에서 제공하는 데이터셋을 R로 가져와서 몇가지 기본 통계 실습을 진행해 볼 것 입니다.

#01. 일반적인 데이터 분석 과정

  1. 데이터 수집
    • 오프라인 설문조사
    • CSV, Excel 등의 파일 가져오기
    • OpenAPI 연동
    • 웹 사이트로부터 데이터 수집 (크롤링)
    • DATABASE 시스템 연동 등 (SQL이라는 또 다른 언어의 학습필요)
  2. 데이터 빈도 확인
    • 상자그림이나 히스토그램
  3. 데이터 정제
    • 결측치와 이상치를 확인하고 정제한다.
  4. 변수 검토 및 데이터 전처리
    • 분석에 사용할 변수들을 전처리한다.
    • 변수의 특성을 파악하고 이상치를 정제한 다음 파생변수를 만든다.
    • 전처리는 분석에 활용할 변수 각각에 대해 실시한다. (한번에 처리 X)
      • 예) “성별에 따른 월급 차이”를 분석한다면 성별, 월급 두 변수를 각각 전처리 한다.
  5. 변수 간 관계 분석 후 시각화
    • 데이터를 요약한 표를 만든 후 분석 결과를 쉽게 이해할 수 있는 그래프를 만든다.

#02. 한국복지패널 데이터 확인

한국복지패널 웹 사이트에서 다운로드 가능.

압축파일을 해제하면 4종류의 파일이 존재한다.

  1. 가구용데이터(SAS, SPSS, STATA): koweps_h12_2017_beta1
  2. 가구원용데이터(SAS, SPSS, STATA): koweps_p12_2017_beta1
  3. 장애인설문용데이터(SAS, SPSS, STATA): koweps_da12_2017_beta1
  4. 가구용, 가구원용, 장애인설문용 통합데이터(SAS, SPSS, STATA): koweps_hpda12_2017_beta1

실습에서는 통합데이터 활용.

예제에서 사용될 변수들의 의미

변수명 설명 내용 범위 모름/무응답
h12_g3 성별 1.남 N(1~2) 모름/무응답=9
    2.여    
h12_g4 태어난 연도 N(1900~2014) 모름/무응답=9999
h12_g10 혼인상태 0.비해당(18세 미만) N(0~6) 모름/무응답=9
    1.유배우    
    2.사별    
    3.이혼    
    4.별거    
    5.미혼(18세이상, 미혼모 포함)    
    6.기타(사망 등)    
h12_g11 종교 1.있음 N(1~2) 모름/무응답=9
    2.없음    
h12_eco9 직종 직종 코드표 참조 N(직종코드 시트참조) 모름/무응답=9999
p1202_8aq1 일한달의 월 평균 임금 만원 N(1~9998) 모름/무응답=9999
h12_reg7 7개 권역별 지역구분 1. 서울 N(1~7)  
    2. 수도권(인천/경기)    
    3. 부산/경남/울산    
    4.대구/경북    
    5. 대전/충남    
    6. 강원/충북    
    7.광주/전남/전북/제주도    

#03. 필요한 패키지 설치 및 로드

1) 패키지 가져오기

한국복지패널 데이터는 SPSS라는 통계분석 툴을 사용하여 생성된 데이터 셋이므로 csv나 xlsx와는 다르게 foreign 패키지를 사용하여 로드해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
# 라이브러리 내려받기
REPO_URL <- "https://cran.seoul.go.kr/"
if (!require(foreign)) install.packages("foreign", repos=REPO_URL)
if (!require(dplyr)) install.packages("dplyr", repos=REPO_URL)
if (!require(ggplot2)) install.packages("ggplot2", repos=REPO_URL)
if (!require("reshape2"))     install.packages("reshape2", repos=REPO_URL)

# 라이브러리 로드
library(foreign)  # SPSS용 데이터 파일을 읽어들일 수 있는 기능을 제공한다.
library(dplyr)
library(ggplot2)
library(reshape2) # 피벗테이블 구성을 위한 패키지

2) 데이터셋 가져오기

foreign 패키지를 사용하여 데이터 불러온다.

  • to.data.frame=TRUE을 설정하지 않으면 데이터를 list 형태로 불러온다.
  • 데이터를 가져오는 과정에서 발생하는 경고메시지 무시.

데이터 로드에 다소 시간이 소요된다.

1
2
3
4
5
원본데이터 <- read.spss(file="http://itpaper.co.kr/demo/r/Koweps_hpda12_2017_beta1.sav",
                     to.data.frame=TRUE)

# 데이터가 매우 크므로 상위 6건만 확인
head(원본데이터)
▶ 출력결과

A data.frame: 6 × 1191

h12_idh12_indh12_snh12_merkeyh_newh12_cobfp12_wglp12_wslp12_wgcp12_wscda12_326da12_327da12_328da12_6aq14da12_6aq15h12_pers_income1h12_pers_income2h12_pers_income3h12_pers_income4h12_pers_income5
<dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl><dbl>
111101010NA 953.48210.2869431 948.14050.2853356NANANANANANA NA NA0NA
211201010NA1238.89140.37283481238.89140.3728348NANANANANANA NA NA0NA
311301010NA1282.05190.38582361282.05190.3858236NANANANANANA NA NA0NA
411401010NA1066.32720.32090291066.32720.3209029NANANANANANA3418 NA0NA
411401010NA1390.61720.41849551382.82680.4161510NANANANANANA NA NA0NA
611601010NA2347.62200.70649872322.32330.6988853NANANANANANA NA53960NA

04. 조사대상들에 대한 성별 분포 조사하기

1) 데이터 전처리

성별 컬럼만 추출

남자는 1, 여자는 2로 표현된다.

1
2
성별추출 <- 원본데이터 %>% select('h12_g3')
head(성별추출)
▶ 출력결과

A data.frame: 6 × 1

h12_g3
<dbl>
2
2
1
1
2
1

성별 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
성별df <- rename(성별추출, 성별코드=h12_g3)
head(성별df)
▶ 출력결과

A data.frame: 6 × 1

성별코드
<dbl>
2
2
1
1
2
1

이상치 여부를 알기 위해 값의 빈도 확인

1
table(성별df$성별코드)
▶ 출력결과
1
2
   1    2
6982 8440

성별값을 남자, 여자로 변환

이상치(9=모름,무응답)가 없기 때문에 별도의 정제과정 없이 1남자, 2여자로 변환한다.

1
2
성별df <- 성별df %>% mutate(성별 = ifelse(성별코드 == 1, '남자', '여자'))
head(성별df)
▶ 출력결과

A data.frame: 6 × 2

성별코드성별
<dbl><chr>
2여자
2여자
1남자
1남자
2여자
1남자

2) 시각화

빈도막대그래프는 ggplot2 패키지가 데이터 빈도를 계산하기 위한 분석과정을 자동으로 처리하기 때문에 별도의 분석과정을 생략할 수 있다.

그래프 크기 및 기본 옵션
1
options(repr.plot.width=15, repr.plot.height=10, warn=-1)
그래프 표현하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ggplot(data=성별df) +
    geom_bar(aes(x=성별, fill=성별)) +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("성별 분포") +
    # x축 제목 설정
    xlab("성별") +
    # y축 제목 설정
    ylab("분포수(명)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 10000, 1000))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=16, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=16, angle=0)) +
    # 범주 설정
    theme(legend.title = element_blank(),
          legend.text = element_text(family="NanumGothic", face="bold", size=15, color="#330066"),
          legend.key = element_rect(color="red", fill="white"),
          legend.key.size = unit(1,"cm"),
          legend.box.background = element_rect(fill="skyblue"),
          legend.box.margin = margin(6, 6, 6, 6))
▶ 출력결과

png

#05. 성별에 따른 평균 월급 차이 분석

1) 데이터 전처리

성별과 월급 데이터만 추출

1
2
성별월급추출 <- 원본데이터 %>% select('h12_g3', 'p1202_8aq1')
head(성별월급추출)
▶ 출력결과

A data.frame: 6 × 2

h12_g3p1202_8aq1
<dbl><dbl>
2 NA
2 NA
1 NA
1108.9
2 NA
1 NA

성별과 월급 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
성별월급df <- rename(성별월급추출, 성별코드=h12_g3, 월급=p1202_8aq1)
head(성별월급df)
▶ 출력결과

A data.frame: 6 × 2

성별코드월급
<dbl><dbl>
2 NA
2 NA
1 NA
1108.9
2 NA
1 NA

성별값을 남자, 여자로 변환

성별 데이터에는 이상치(9=모름,무응답)가 없기 때문에 별도의 정제과정 없이 1남자, 2여자로 변환한다.

1
2
성별월급df <- 성별월급df %>% mutate(성별 = ifelse(성별코드 == 1, '남자', '여자'))
head(성별월급df)
▶ 출력결과

A data.frame: 6 × 3

성별코드월급성별
<dbl><dbl><chr>
2 NA여자
2 NA여자
1 NA남자
1108.9남자
2 NA여자
1 NA남자

2) 데이터 정제

결측치 확인

1
colSums(is.na(성별월급df))
▶ 출력결과
1
2
3
성별코드    0
월급        10915
성별        0

결측치 소거

성별월급df의 정제된 결과를 다시 정제df에 저장

1
2
정제df <- 성별월급df %>% filter(!is.na(월급))
head(정제df)
▶ 출력결과

A data.frame: 6 × 3

성별코드월급성별
<dbl><dbl><chr>
1108.9남자
2 20.0여자
1322.0남자
2120.0여자
1300.0남자
2100.0여자

정제결과 확인

1
colSums(is.na(정제df))
▶ 출력결과
1
2
3
성별코드    0
월급        0
성별        0

이상치 결측 처리

  • 코드표에 의하면 월급 데이터의 경우 1~9998 사이의 값을 갖는다고 되어 있다.
  • 모름/무응답의 경우 9999로 저장되며 0인 경우는 데이터가 없는 상태이므로 이 두 상태를 이상치로 봐야 한다.

여기서는 정제df의 처리결과를 다시 정제df에 덮어 씌움

1
2
정제df <- 정제df %>% mutate(월급 = ifelse(월급 %in% c(0, 9999), NA, 월급))
head(정제df)
▶ 출력결과

A data.frame: 6 × 3

성별코드월급성별
<dbl><dbl><chr>
1108.9남자
2 20.0여자
1322.0남자
2120.0여자
1300.0남자
2100.0여자

이상치의 정제 결과로 생성된 결측치 확인

1
colSums(is.na(정제df))
▶ 출력결과
1
2
3
성별코드    0
월급        14
성별        0

결측치 소거

1
2
성별월급완성df <- 정제df %>% filter(!is.na(월급))
head(성별월급완성df)
▶ 출력결과

A data.frame: 6 × 3

성별코드월급성별
<dbl><dbl><chr>
1108.9남자
2 20.0여자
1322.0남자
2120.0여자
1300.0남자
2100.0여자

정제결과 확인

1
colSums(is.na(성별월급완성df))
▶ 출력결과
1
2
3
성별코드    0
월급        0
성별        0

3) 데이터 분석

성별로 그룹화하여 그룹별 평균 구하기

1
2
3
4
분석결과df <- 성별월급완성df %>%
                    group_by(성별) %>%
                    summarise(평균월급 = mean(월급, na.rm=TRUE))
분석결과df
▶ 출력결과

A tibble: 2 × 2

성별평균월급
<chr><dbl>
남자333.4222
여자176.3600

4) 데이터 시각화

수치값을 모두 산정해 놓은 결과를 토대로 그래프를 만드는 경우 평균막대그래프를 사용

텍스트 색상, 크기, 각도, 글꼴 설정 및 범주 설정 코드는 앞 예제와 동일하게 적용하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ggplot(data=분석결과df) +
    geom_col(aes(x=성별,y=평균월급,fill=성별)) +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("성별 평균 월급") +
    # x축 제목 설정
    xlab("성별") +
    # y축 제목 설정
    ylab("평균월급(만원)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 350, 50))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=16, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=16, angle=0)) +
    # 범주 설정
    theme(legend.title = element_blank(),
          legend.text = element_text(family="NanumGothic", face="bold", size=15, color="#330066"),
          legend.key = element_rect(color="red", fill="white"),
          legend.key.size = unit(1,"cm"),
          legend.box.background = element_rect(fill="skyblue"),
          legend.box.margin = margin(6, 6, 6, 6))
▶ 출력결과

png

#06. 나이에 따른 평균 월급의 변화

1) 데이터 전처리

태어난 년도,월급에 대한 컬럼 추출

1
2
년도월급추출 <- 원본데이터 %>% select('h12_g4', 'p1202_8aq1')
head(년도월급추출)
▶ 출력결과

A data.frame: 6 × 2

h12_g4p1202_8aq1
<dbl><dbl>
1936 NA
1945 NA
1948 NA
1942108.9
1923 NA
1962 NA

태어난 년도와 월급 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
년도월급df <- rename(년도월급추출, 태어난년도=h12_g4, 월급=p1202_8aq1)
head(년도월급df)
▶ 출력결과

A data.frame: 6 × 2

태어난년도월급
<dbl><dbl>
1936 NA
1945 NA
1948 NA
1942108.9
1923 NA
1962 NA

나이를 계산하여 파생변수 추가

현재 년도 구하기
1
2
3
now_year <- format(Sys.time(), "%Y")
typeof(now_year)
now_year
▶ 출력결과
1
2
'character'
'2020'
정수로 변환

계산된 년도 값이 문자열이므로 나이 계산을 위해 숫자형으로 변환한다.

1
2
3
now_year_numeric <- as.numeric(now_year)
typeof(now_year_numeric)
now_year_numeric
▶ 출력결과
1
2
'double'
2020
나이 계산

현재년도 - 태어난년도 + 1

1
2
나이월급df <- 년도월급df %>% mutate(나이 = now_year_numeric - 태어난년도 + 1)
head(나이월급df)
▶ 출력결과

A data.frame: 6 × 3

태어난년도월급나이
<dbl><dbl><dbl>
1936 NA85
1945 NA76
1948 NA73
1942108.979
1923 NA98
1962 NA59

2) 데이터 정제

월급 데이터에 대한 정제과정은 앞에서 확인한 바와 같이 0이나 9999인 데이터를 이상치로 지정한 후 결측치 소거법을 적용한다.

1
2
3
4
5
6
7
# 데이터 이상치, 결측치 정제
나이월급완성df <- 나이월급df %>%
                mutate(월급 = ifelse(월급 %in% c(0, 9999), NA, 월급)) %>%
                filter(!is.na(월급))

# 정제 결과 확인
colSums(is.na(나이월급완성df))
▶ 출력결과
1
2
3
태어난년도  0
월급        0
나이        0

3) 데이터 분석

1
2
3
4
분석결과df <- 나이월급완성df %>%
                group_by(나이) %>%
                summarise(평균월급 = mean(월급, na.rm=TRUE))
head(분석결과df)
▶ 출력결과

A tibble: 6 × 2

나이평균월급
<dbl><dbl>
23 89.33333
24136.72000
25140.80769
26138.00000
27145.65200
28166.66667

4) 시각화

그래프 크기 설정 및 경고 메시지 끄기
1
options(repr.plot.width=15, repr.plot.height=10, warn=-1)
선 그래프 표시하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ggplot(data = 분석결과df) +
    geom_line(aes(x=나이, y=평균월급), color="#ff6600") +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("나이에 따른 평균 월급 변화") +
    # x축 제목 설정
    xlab("나이") +
    # y축 제목 설정
    ylab("평균월급(만원)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 350, 30))  +
    # x축 간격 및 데이터에 대한 세자리 콤마 적용
    scale_x_continuous(breaks=seq(min(분석결과df$나이), max(분석결과df$나이), 5))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0))
▶ 출력결과

png

#07. 연령대 분포

1) 데이터 전처리

태어난 년도 컬럼 추출

1
2
년도추출df <- 원본데이터 %>% select('h12_g4')
head(년도추출df)
▶ 출력결과

A data.frame: 6 × 1

h12_g4
<dbl>
1936
1945
1948
1942
1923
1962

태어난 년도 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
년도df <- rename(년도추출df, 태어난년도=h12_g4)
head(년도df)
▶ 출력결과

A data.frame: 6 × 1

태어난년도
<dbl>
1936
1945
1948
1942
1923
1962

태어난 년도에서 나이를 계산하여 파생변수 추가

현재 년도는 앞에서 미리 조회한 값을 재사용한다.

1
2
년도나이df <- 년도df %>% mutate(나이 = now_year_numeric - 태어난년도 + 1)
head(년도나이df)
▶ 출력결과

A data.frame: 6 × 2

태어난년도나이
<dbl><dbl>
193685
194576
194873
194279
192398
196259

나이 컬럼에서 연령대를 계산하여 파생변수 추가

나이를 10으로 나눈 정수 부분의 몫만 구한 후 다시 10을 곱하면 연령대를 얻을 수 있다.

28세 –> 28 %/% 10 –> 2
2 * 10 –> 20대

1
2
연령대df <- 년도나이df %>% mutate(연령대 = (나이 %/% 10) * 10)
head(연령대df)
▶ 출력결과

A data.frame: 6 × 3

태어난년도나이연령대
<dbl><dbl><dbl>
19368580
19457670
19487370
19427970
19239890
19625950

2) 데이터 정제

결측치 확인

1
colSums(is.na(연령대df))
▶ 출력결과
1
2
3
태어난년도  0
나이        0
연령대      0

연령대에 대한 데이터 타입 변환

막대그래프의 x축은 연속형 데이터가 아니라 범주형이나 문자형이어야 하므로 요인 타입으로 변경한다.

1
2
연령대df$연령대 <- factor(연령대df$연령대)
head(연령대df)
▶ 출력결과

A data.frame: 6 × 3

태어난년도나이연령대
<dbl><dbl><fct>
19368580
19457670
19487370
19427970
19239890
19625950

3) 빈도 그래프로 시각화 하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ggplot(data=연령대df) +
    geom_bar(aes(x=연령대, fill=연령대)) +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("연령대 분포") +
    # x축 제목 설정
    xlab("연령대") +
    # y축 제목 설정
    ylab("사람수(명)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 3000, 500))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0)) +
    # 범주 설정
    theme(legend.title = element_blank(),
          legend.text = element_text(family="NanumGothic", face="bold", size=15, color="#330066"),
          legend.key = element_rect(color="red", fill="white"),
          legend.key.size = unit(1,"cm"),
          legend.box.background = element_rect(fill="skyblue"),
          legend.box.margin = margin(6, 6, 6, 6))

png

#08. 연령대별 평균 급여의 변화

1) 데이터 전처리

태어난 년도, 월급 컬럼 추출

1
2
년도월급추출df <- 원본데이터 %>% select('h12_g4', 'p1202_8aq1')
head(년도월급추출df)
▶ 출력결과

A data.frame: 6 × 2

h12_g4p1202_8aq1
<dbl><dbl>
1936 NA
1945 NA
1948 NA
1942108.9
1923 NA
1962 NA

태어난 년도와 월급 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
년도월급df <- rename(년도월급추출df, 태어난년도=h12_g4, 월급=p1202_8aq1)
head(년도월급df)
▶ 출력결과

A data.frame: 6 × 2

태어난년도월급
<dbl><dbl>
1936 NA
1945 NA
1948 NA
1942108.9
1923 NA
1962 NA

파생변수 추가

  • 태어난 년도 컬럼에서 연령대를 계산
  • 나이 컬럼에서 연령대를 계산
1
2
3
4
결과df <- 년도월급df %>%
            mutate(나이 = now_year_numeric - 태어난년도 + 1,
                   연령대 = (나이 %/% 10) * 10)
head(결과df)
▶ 출력결과

A data.frame: 6 × 4

태어난년도월급나이연령대
<dbl><dbl><dbl><dbl>
1936 NA8580
1945 NA7670
1948 NA7370
1942108.97970
1923 NA9890
1962 NA5950

2) 데이터 정제

월급에 대한 이상치, 결측치 정제

1
2
3
4
5
6
7
# 데이터 이상치, 결측치 정제
연령대월급df <- 결과df %>%
                 mutate(월급 = ifelse(월급 %in% c(0, 9999), NA, 월급)) %>%
                 filter(!is.na(월급))

# 정제 결과 확인
colSums(is.na(연령대월급df))
▶ 출력결과
1
2
3
4
태어난년도  0
월급        0
나이        0
연령대      0

3) 데이터 분석

연령대별 평균 월급 계산

1
2
3
4
연령대평균월급df <- 연령대월급df %>%
                       group_by(연령대) %>%
                       summarise(평균월급 = mean(월급, na.rm=TRUE))
head(연령대평균월급df)
▶ 출력결과

A tibble: 6 × 2

연령대평균월급
<dbl><dbl>
20154.8905
30248.0583
40329.4909
50314.7544
60226.8461
70 94.1491

4) 데이터 시각화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ggplot(data=연령대평균월급df) +
    geom_line(aes(x=연령대, y=평균월급), color="#ff6600") +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("연령대에 따른 평균 월급 변화") +
    # x축 제목 설정
    xlab("연령대") +
    # y축 제목 설정
    ylab("평균월급(만원)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 350, 30))  +
    # x축 간격
    scale_x_continuous(breaks=seq(min(연령대평균월급df$연령대), max(연령대평균월급df$연령대), 10))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0))
▶ 출력결과

png

#09. 성별과 연령대 분포

1) 데이터 전처리

성별과 태어난 년도 데이터 추출

1
2
성별년도추출df <- 원본데이터 %>% select('h12_g3', 'h12_g4')
head(성별년도추출df)
▶ 출력결과

A data.frame: 6 × 2

h12_g3h12_g4
<dbl><dbl>
21936
21945
11948
11942
21923
11962

성별과 태어난 년도 변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
성별년도df <- rename(성별년도추출df, 성별코드=h12_g3, 태어난년도=h12_g4)
head(성별년도df)
▶ 출력결과

A data.frame: 6 × 2

성별코드태어난년도
<dbl><dbl>
21936
21945
11948
11942
21923
11962

파생변수 추가

  • 성별값을 남자, 여자로 변환
  • 태어난 년도에서 나이 컬럼 추가
  • 나이 컬럼을 통해 연령대 컬럼 추가
1
2
3
4
5
결과df <- 성별년도df %>%
            mutate(성별 = ifelse(성별코드 == 1, '남자', '여자'),
                   나이 = now_year_numeric - 태어난년도 + 1,
                   연령대 = (나이 %/% 10) * 10)
head(결과df)
▶ 출력결과

A data.frame: 6 × 5

성별코드태어난년도성별나이연령대
<dbl><dbl><chr><dbl><dbl>
21936여자8580
21945여자7670
11948남자7370
11942남자7970
21923여자9890
11962남자5950

2) 데이터 시각화

geom_bar() 함수를 사용하여 연령대와 성별에 대한 빈도 그래프를 구하면 각 값의 종류별로 빈도수 계산이 자동으로 이루어 진다.

이는 각 성별,연령대별의 사람 수를 의미하므로 별도의 집계 수행은 수행하지 않아도 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ggplot(data=결과df) +
    geom_bar(aes(x=연령대, fill=factor(성별)), position='dodge')+
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("성별과 연령대 분포") +
    # x축 제목 설정
    xlab("연령대") +
    # y축 제목 설정
    ylab("사람수(명)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 1500, 200))  +
    # x축 간격
    scale_x_continuous(breaks=seq(min(결과df$연령대), max(결과df$연령대), 10))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0)) +
    # 범주 설정
    theme(legend.title = element_blank(),
          legend.text = element_text(family="NanumGothic", face="bold", size=15, color="#330066"),
          legend.key = element_rect(color="red", fill="white"),
          legend.key.size = unit(1,"cm"),
          legend.box.background = element_rect(fill="skyblue"),
          legend.box.margin = margin(6, 6, 6, 6))
▶ 출력결과

png

#10. 성별과 연령대에 따른 평균 급여 변화

1) 데이터 전처리

성별과 태어난년도, 월급 데이터 추출

1
2
성별년도급여추출 <- 원본데이터 %>% select('h12_g3', 'h12_g4', 'p1202_8aq1')
head(성별년도급여추출)
▶ 출력결과

A data.frame: 6 × 3

h12_g3h12_g4p1202_8aq1
<dbl><dbl><dbl>
21936 NA
21945 NA
11948 NA
11942108.9
21923 NA
11962 NA

변수의 이름을 인식하기 쉬운 값으로 변경하기

1
2
성별년도급여df = rename(성별년도급여추출, 성별코드=h12_g3, 태어난년도=h12_g4, 월급=p1202_8aq1)
head(성별년도급여df)
▶ 출력결과

A data.frame: 6 × 3

성별코드태어난년도월급
<dbl><dbl><dbl>
21936 NA
21945 NA
11948 NA
11942108.9
21923 NA
11962 NA

연령대 계산, 성별 컬럼에 대한 값 변경

1
2
3
4
5
전처리df <- 성별년도급여df %>%
            mutate(성별 = ifelse(성별코드 == 1, '남자', '여자'),
                   나이 = now_year_numeric - 태어난년도 + 1,
                   연령대 = (나이 %/% 10) * 10)
head(전처리df)
▶ 출력결과

A data.frame: 6 × 6

성별코드태어난년도월급성별나이연령대
<dbl><dbl><dbl><chr><dbl><dbl>
21936 NA여자8580
21945 NA여자7670
11948 NA남자7370
11942108.9남자7970
21923 NA여자9890
11962 NA남자5950

2) 데이터 정제

월급 데이터에 대한 처리

월급 데이터가 0이거나 9999인 값들이 이상치이므로 해당 값들을 결측치로 대체하고 전체 결측치들을 소거한다.

1
2
3
4
5
6
7
# 데이터 이상치, 결측치 정제
정제df <- 전처리df %>%
            mutate(월급 = ifelse(월급 %in% c(0, 9999), NA, 월급)) %>%
            filter(!is.na(월급))

# 정제 결과 확인
colSums(is.na(정제df))
▶ 출력결과
1
2
3
4
5
6
성별코드    0
태어난년도  0
월급        0
성별        0
나이        0
연령대      0

3) 데이터 분석

성별과 연령대에 따른 평균 급여

1
2
3
성별_연령대별_평균급여df <- 정제df %>% group_by(성별, 연령대) %>%
                        summarise(평균월급 = mean(월급, na.rm=TRUE))
성별_연령대별_평균급여df
▶ 출력결과

A grouped_df: 16 × 3

성별연령대평균월급
<chr><dbl><dbl>
남자20156.18182
남자30274.75959
남자40400.57499
남자50413.41027
남자60305.55524
남자70131.13099
남자80 42.54545
남자90 20.00000
여자20154.32229
여자30218.52500
여자40222.40912
여자50197.96186
여자60141.09198
여자70 66.79792
여자80 29.93902
여자90 22.50000

피벗테이블 구성

1
2
pivot <- dcast(성별_연령대별_평균급여df, 연령대~성별, value.var="평균월급")
pivot
▶ 출력결과

A data.frame: 8 × 3

연령대남자여자
<dbl><dbl><dbl>
20156.18182154.32229
30274.75959218.52500
40400.57499222.40912
50413.41027197.96186
60305.55524141.09198
70131.13099 66.79792
80 42.54545 29.93902
90 20.00000 22.50000

4) 데이터 시각화

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ggplot(data=pivot) +
    geom_line(aes(x=연령대, y=남자), color="#0b57e3") +
    geom_line(aes(x=연령대, y=여자), color="#ff6600") +
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("연령대에 따른 평균 월급 변화") +
    # x축 제목 설정
    xlab("연령대") +
    # y축 제목 설정
    ylab("평균월급(만원)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 500, 50))  +
    # x축 간격
    scale_x_continuous(breaks=seq(min(연령대평균월급df$연령대), max(연령대평균월급df$연령대), 10))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0))
▶ 출력결과

png

#11. 지역별 연령층 분포

1) 데이터 전처리

데이터 추출하기

1
2
지역년도추출 <- 원본데이터 %>% select('h12_g4', 'h12_reg7')
head(지역년도추출)
▶ 출력결과

A data.frame: 6 × 2

h12_g4h12_reg7
<dbl><dbl>
19361
19451
19481
19421
19231
19621

변수명 변경

1
2
지역년도df <- rename(지역년도추출, 태어난년도=h12_g4, 지역코드=h12_reg7)
head(지역년도df)
▶ 출력결과

A data.frame: 6 × 2

태어난년도지역코드
<dbl><dbl>
19361
19451
19481
19421
19231
19621

지역코드와 매칭될 지역명 코드표 만들기

1
2
3
4
지역코드df <- data.frame(지역코드 = seq(1, 7),
                       지역명 = c("서울", "인천,경기", "부산,경남,울산", "대구,경북", "대전,충남", "강원,충북", "광주,전남,전북,제주"))

지역코드df
▶ 출력결과

A data.frame: 7 × 2

지역코드지역명
<int><fct>
1서울
2인천,경기
3부산,경남,울산
4대구,경북
5대전,충남
6강원,충북
7광주,전남,전북,제주

원래의 데이터 프레임에 지역코드표 병합

양쪽의 데이터프레임에서 공통되는 컬럼을 기준으로 병합.

1
2
지역명추가df <- left_join(지역년도df, 지역코드df, by="지역코드")
head(지역명추가df)
▶ 출력결과

A data.frame: 6 × 3

태어난년도지역코드지역명
<dbl><dbl><fct>
19361서울
19451서울
19481서울
19421서울
19231서울
19621서울

나이 변수 추가

1
2
나이추가df <- 지역명추가df %>% mutate(나이 = now_year_numeric - 태어난년도 + 1)
head(나이추가df)
▶ 출력결과

A data.frame: 6 × 4

태어난년도지역코드지역명나이
<dbl><dbl><fct><dbl>
19361서울85
19451서울76
19481서울73
19421서울79
19231서울98
19621서울59

2) 데이터 정제

결측치 검사

결측치가 검출되지 않았으므로 다음 과정을 진행한다.

1
colSums(is.na(나이추가df))
▶ 출력결과
1
2
3
4
태어난년도  0
지역코드    0
지역명      0
나이        0

3) 데이터 분석

연령층 구분

1
2
3
4
연령층구분df <- 나이추가df %>% mutate(연령층=case_when(나이 < 30 ~ "청년층",
                                                나이 < 60 ~ "중년층",
                                                TRUE ~ "노년층"))
head(연령층구분df)
▶ 출력결과

A data.frame: 6 × 5

태어난년도지역코드지역명나이연령층
<dbl><dbl><fct><dbl><chr>
19361서울85노년층
19451서울76노년층
19481서울73노년층
19421서울79노년층
19231서울98노년층
19621서울59중년층

지역과 연령층에 대한 그룹분석

1
2
3
지역별연령층df = 연령층구분df %>% group_by(지역명,연령층) %>%
                            summarise(조사인원 = n())
지역별연령층df
▶ 출력결과

A grouped_df: 21 × 3

지역명연령층조사인원
<fct><chr><int>
강원,충북 노년층 567
강원,충북 중년층 361
강원,충북 청년층 252
광주,전남,전북,제주노년층1283
광주,전남,전북,제주중년층 867
광주,전남,전북,제주청년층 599
대구,경북 노년층 973
대구,경북 중년층 537
대구,경북 청년층 364
대전,충남 노년층 591
대전,충남 중년층 443
대전,충남 청년층 321
부산,경남,울산 노년층1189
부산,경남,울산 중년층 844
부산,경남,울산 청년층 531
서울 노년층 858
서울 중년층 868
서울 청년층 482
인천,경기 노년층1227
인천,경기 중년층1335
인천,경기 청년층 930

분석결과를 피벗테이블로 구성

피벗 테이블 구성시 컬럼명의 순서는 오름차순이 기본으로 적용된다.

1
2
지역별연령층pv <- dcast(지역별연령층df, 지역명~연령층, value.var="조사인원")
지역별연령층pv
▶ 출력결과

A data.frame: 7 × 4

지역명노년층중년층청년층
<fct><int><int><int>
강원,충북 567 361252
광주,전남,전북,제주1283 867599
대구,경북 973 537364
대전,충남 591 443321
부산,경남,울산 1189 844531
서울 858 868482
인천,경기 12271335930

컬럼순서 변경

1
2
지역별연령층결과df <- 지역별연령층pv[, c('지역명', '청년층', '중년층', '노년층')]
지역별연령층결과df
▶ 출력결과

A data.frame: 7 × 4

지역명청년층중년층노년층
<fct><int><int><int>
강원,충북 252 361 567
광주,전남,전북,제주599 8671283
대구,경북 364 537 973
대전,충남 321 443 591
부산,경남,울산 531 8441189
서울 482 868 858
인천,경기 93013351227

4) 데이터 시각화

1) 각 지역별 연령층 분포 비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ggplot(data=지역별연령층df) +
    geom_col(aes(x=지역명, y=조사인원, fill=연령층), position='dodge')+
    # 배경을 흰색으로 설정
    theme_bw() +
    # 그래프 타이틀 설정
    ggtitle("성별과 연령대 분포") +
    # x축 제목 설정
    xlab("연령대") +
    # y축 제목 설정
    ylab("사람수(명)") +
    # y축 간격
    scale_y_continuous(breaks=seq(0, 1500, 100))  +
    # 각 텍스트의 색상, 크기, 각도, 글꼴 설정
    theme(plot.title=element_text(family="NanumGothic", color="#0066ff", size=25, face="bold", hjust=0.5),
          axis.title.x=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.title.y=element_text(family="NanumGothic", color="#999999", size=18, face="bold"),
          axis.text.x=element_text(family="NanumGothic", color="#000000", size=14, angle=0),
          axis.text.y=element_text(family="NanumGothic", color="#000000", size=14, angle=0)) +
    # 범주 설정
    theme(legend.title = element_blank(),
          legend.text = element_text(family="NanumGothic", face="bold", size=15, color="#330066"),
          legend.key = element_rect(color="red", fill="white"),
          legend.key.size = unit(1,"cm"),
          legend.box.background = element_rect(fill="skyblue"),
          legend.box.margin = margin(6, 6, 6, 6))
▶ 출력결과

png

Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[R 데이터 분석,시각화] 한국복지패널 데이터 분석 실습≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus