영국의 극작가이자 소설가인 오스카 와일드가 쓴 희곡 진지함의 중요성(The Importance of Being Earnest)을 구텐베르그(gutenberg) 웹사이트에서 다운로드 받아 희곡에 등장하는 인물들의 대사횟수를 기준으로 중요도를 추출해본다.
stringr
, stringi
, rebus
팩키지는 텍스트, 문자열 처리를 위한 R 3종 세트 팩키지라 바로 불러오고 나서, tidyverse
팩키지를 통해 데이터를 정제하는데 사용한다.
“진지함의 중요성” 희곡은 readLines()
함수에 구텐베르그 사이트 url을 바로 넣어 가져온다.
# 0. 환경설정 ---------------------------
#library(rebus)
#library(stringr)
#library(stringi)
#library(tidyverse)
# 1. 데이터 가져오기 -------------------
text_844 <- readLines("http://www.gutenberg.org/cache/epub/844/pg844.txt")
구텐베르그 프로젝트에 앞뒤 쪽 진지함의 중요성 희곡본문 내용을 감싼 내용이 있어 이를 제거하고, 도입부와 연극 본문의 내용을 구분한다.
# 2. 데이터 정제 -------------------
## 2.1. 소설 본문 추출 시작과 끝 ------------------
start_line <- which(str_detect(text_844, pattern = fixed("START OF THE PROJECT")))
end_line <- which(str_detect(text_844, pattern = fixed("END OF THE PROJECT")))
## 2.2. 소설 본문 추출
text_only <- text_844[(start_line+1):(end_line-1)]
## 2.3. 도입(Intro)과 연극(Play) 구분
cutoff_line <- which(str_detect(text_only, pattern = fixed("FIRST ACT")))
cutoff_line_index <- 1:(cutoff_line-1)
## 2.4. 도입부와 연극으로 구분
intro_text <- text_only[cutoff_line_index]
play_text <- text_only[-cutoff_line_index]
정규식을 적용하여 배우를 추출한다. “진지함의 중요성”에 총 9 명 배우가 나오는 사실은 알고 있으니, 이를 등장인물 characters
로 정의하고 해당되는 행(라인)을 추출한다.
# 3. 출연 비중이 높은 배우 데이터 추출 ----------------------
## 3.1. 출연배우 정의 후 정규식 적용
characters <- c("Algernon", "Jack", "Lane", "Cecily", "Gwendolen", "Chasuble",
"Merriman", "Lady Bracknell", "Miss Prism")
## 3.2. 정규식
char_pattern <- START %R% or1(characters) %R% DOT
## 3.3. 정규식 적용결과 확인
str_view(play_text, char_pattern, match=TRUE)
str_subset
함수로 등장인물이 출현하는 행을 뽑아낸다. 뽑아낸 행에서 패턴에 매칭되는 등장배우를 str_extract
함수로 추출한다. 그리고 table
함수를 활용하여 등장배우 활동성을 통계내고 이를 표로 작성한다.
# 4. 출연 비중 통계 작업 ----------------------
## 4.1. 정규식 매칭 데이터 라인 추출
char_lines <- str_subset(play_text, char_pattern)
## 4.2. 패턴에 매칭되는 배우 캐릭터 추출
characters <- str_extract(char_lines, char_pattern)
## 4.3. 최다 출연 배우 통계
char_tbl <- table(characters)
# 5. 그래프와 표로 마무리 작업 ----------------------
char_tbl %>% as.data.frame() %>%
dplyr::arrange(desc(Freq)) %>%
mutate(pcnt = Freq/sum(Freq),
cumpcnt = cumsum(pcnt)) %>%
DT::datatable() %>%
DT::formatPercentage(c(3,4), digits = 1)