Reference

Crawling

- 위키피디아에서 조선의 국와 정보를 크롤링합니다.

if (!require(rvest)) install.packages('rvest')
library(rvest)

if (!require(tidyverse)) install.packages('tidyverse')
library(tidyverse)

get_required_info = function(rows, order){
    clean_table = rows[order] %>% # 한글자씩 쪼갠다.
        strsplit(split = '') %>%
        unlist() %>%
        str_replace('[^가-힣0-9]', 'N')  %>% # (한글, 숫자)가 아닌 문자는 불필요하므로 N으로 치환한다.
        paste(collapse = '') %>% # 모든 문자를 합친 다음 N을 기준으로 다시 나눈다.
        strsplit('N') %>%
        unlist()

    order_index = grep('^제.{1,}대$', clean_table)
    order = clean_table[order_index]
    
    name_index = grep('^.{1,2}[조|종|군]$', clean_table)[1]
    name = clean_table[name_index]

    years_index = grep('^.{1,}년$', clean_table)
    years <- # 순서대로 출생, 사망, 즉위, 퇴위
        clean_table[years_index] %>%
        substr(1, 4)

    grave_index = grep('^.{1,3}[릉|묘]$', clean_table)
    grave = clean_table[grave_index]
    
    return(c(order, name, years, grave))
}

target_url <- 'https://ko.wikipedia.org/wiki/%EC%A1%B0%EC%84%A0_%EA%B5%AD%EC%99%95'
unclean_table <- 
    read_html(target_url, encoding = 'UTF-8') %>%
    html_nodes('table[class=wikitable]') %>%
    html_nodes('tbody') %>%
    html_nodes('tr') %>%    
    html_text() 

# 필요로 하는 데이터는 모두 '제'로 시작한다.
# '제'로 시작하지 않는 데이터는 불필요하므로 제거한다.
requiredRows_index <- str_detect(unclean_table, '^제')
requiredRows <- unclean_table[requiredRows_index]

last_order = 26
kings_info <- vector('list', last_order)
for (i in 1:last_order){
    kings_info[[i]] = get_required_info(requiredRows, i)
}

kings_info = do.call('rbind', kings_info)
colnames(kings_info) = c('order', 'name', 'birth', 'death', 'king_start', 'king_end', 'grave')
write.table(kings_info, 'Joseon_king.txt', row.names=FALSE)
필요한 패키지를 로딩중입니다: rvest

Warning message:
"패키지 'rvest'는 R 버전 4.1.3에서 작성되었습니다"
필요한 패키지를 로딩중입니다: tidyverse

Warning message:
"패키지 'tidyverse'는 R 버전 4.1.3에서 작성되었습니다"
-- Attaching packages ------------------------------------------------------------------------------- tidyverse 1.3.1 --

v ggplot2 3.3.5     v purrr   0.3.4
v tibble  3.1.6     v dplyr   1.0.8
v tidyr   1.2.0     v stringr 1.4.0
v readr   2.1.2     v forcats 0.5.1

Warning message:
"패키지 'ggplot2'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'tibble'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'tidyr'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'readr'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'purrr'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'dplyr'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'stringr'는 R 버전 4.1.3에서 작성되었습니다"
Warning message:
"패키지 'forcats'는 R 버전 4.1.3에서 작성되었습니다"
-- Conflicts ---------------------------------------------------------------------------------- tidyverse_conflicts() --
x dplyr::filter()         masks stats::filter()
x readr::guess_encoding() masks rvest::guess_encoding()
x dplyr::lag()            masks stats::lag()

kings_info
A data.frame: 26 × 9
order name birth death king_start king_end grave age class
<chr> <chr> <dbl> <dbl> <chr> <chr> <chr> <dbl> <fct>
제1대 태조 1335 1408 1392 1398 건원릉 73 Before
제2대 정종 1357 1419 1398 1400 후릉 62 Before
제3대 태종 1367 1422 1400 1418 헌릉 55 Before
제4대 세종 1397 1450 1418 1450 영릉 53 Before
제5대 문종 1414 1452 1450 1452 현릉 38 Before
제6대 단종 1441 1457 1452 1455 장릉 16 Before
제7대 세조 1417 1468 1455 1468 광릉 51 Before
제8대 예종 1450 1469 1468 1469 창릉 19 Before
제9대 성종 1457 1494 1469 1494 선릉 37 Before
제10대 연산군 1476 1506 1494 1506 연산군묘 30 Before
제11대 중종 1488 1544 1506 1544 정릉 56 Before
제12대 인종 1515 1545 1544 1545 효릉 30 Before
제13대 명종 1534 1567 1545 1567 강릉 33 Before
제14대 선조 1552 1608 1567 1608 목릉 56 Before
제15대 광해군 1575 1641 1608 1623 광해군묘 66 Before
제16대 인조 1595 1649 1623 1649 장릉 54 Before
제17대 효종 1619 1659 1649 1659 영릉 40 After
제18대 현종 1641 1674 1659 1674 숭릉 33 After
제19대 숙종 1661 1720 1674 1720 명릉 59 After
제20대 경종 1688 1724 1720 1724 의릉 36 After
제21대 영조 1694 1776 1724 1776 원릉 82 After
제22대 정조 1752 1800 1776 1800 건릉 48 After
제23대 순조 1790 1834 1800 1834 인릉 44 After
제24대 헌종 1827 1849 1834 1849 경릉 22 After
제25대 철종 1831 1863 1849 1863 예릉 32 After
제26대 고종 1852 1919 1863 1897 홍릉 67 After

Analysis

- 왕의 수명을 출생년도 기준으로 동의보감 편찬 이전과 이후로 나누었을 때, 유의미한 차이가 있는가?

kings_info <- data.frame(kings_info)
kings_info[, c('birth', 'death')] =
    kings_info[, c('birth', 'death')] %>% 
    unlist() %>% 
    as.numeric()

kings_info = 
    kings_info %>%
    mutate(age = death - birth)


plot(kings_info$birth, kings_info$age,
     xlab = 'birth_year',
     ylab = 'age',
     main = '동의보감 1610년')

Donguibogam = 1610
abline(v = Donguibogam, col = 'red')
abline(lm(kings_info$age ~ kings_info$birth)) # 회귀선

# 상자그림
kings_info['class'] = 
    ifelse(kings_info['birth'] <= 1610, 'Before', 'After') %>%
    factor(levels = c('Before', 'After'))
            
boxplot(kings_info$age ~ kings_info$class,
        xlab = 'group',
        ylab = 'age',
        main = '동의보감 이전과 이후')