rm(list=ls()) # 기존에 작업하던 데이터, 변량 모두 제거
getwd() # 작업폴더 확인
setwd("C:/study") # 작업폴더 지정
getwd() # 작업폴더 재확인
## In Ch 9 --------------
# library(foreign)
# library(dplyr)
# library(ggplot2)
# library(readxl)
# library(descr)
# library(readxl)
# library(gridExtra)
## In Ch 10 --------------
# library(KoNLP)
# library(dplyr)
# library(stringr)
# library(rJava)
# library(memoise)
# library(wordcloud)
# library(RColorBrewer)
# 데이터 불러오기
raw_welfare <- foreign::read.spss(file = "Koweps_hpc10_2015_beta1.sav",
to.data.frame = T)
## Warning in foreign::read.spss(file = "Koweps_hpc10_2015_beta1.sav",
## to.data.frame = T): Koweps_hpc10_2015_beta1.sav: Compression bias (0) is
## not the usual value of 100
# 복사본 만들기
welfare <- raw_welfare
# 데이터 확인
class(welfare)
## [1] "data.frame"
dim(welfare)
## [1] 16664 957
# 데이터가 너무 커서 dplyr::sample_n 을 사용해서 샘플링 한 데이터만 확인
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
welfare %>%
sample_n(1000) %>%
DT::datatable()
## Warning in instance$preRenderHook(instance): It seems your data is too
## big for client-side DataTables. You may consider server-side processing:
## http://rstudio.github.io/DT/server.html
library(dplyr)
library(ggplot2)
welfare <- welfare %>%
rename(sex = h10_g3, # 성별
birth = h10_g4, # 출생년도
marriage = h10_g10, # 혼인 상태
religion = h10_g11, # 종교
income = p1002_8aq1, # 월급(수입)
code_job = h10_eco9, # 직업 코드
code_region = h10_reg7) # 지역 코드
# 성별 변수 결측치, 이상치 확인 및 처리
descr::CrossTable(welfare$sex)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | 1 | 2 |
## |----------|----------|
## | 7578 | 9086 |
## | 0.455 | 0.545 |
## |----------|----------|
# output 중에서 1은 남성, 2는 여성을 뜻함
# 결측치가 존재하지 않음을 알 수 있다.
# 성별 변수 factor 변수로 변환
welfare <- welfare %>%
mutate(sex = ifelse(sex == 1, "male", "female"))
descr::CrossTable(welfare$sex)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | female | male |
## |----------|----------|
## | 9086 | 7578 |
## | 0.545 | 0.455 |
## |----------|----------|
qplot(welfare$sex)
# 월급 변수
# qplot으로는 0, 9999값(결측치)의 존재성과 갯수 파악이 힘들어서 다음과 같이 실행.
summary(welfare$income)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0 122.0 192.5 241.6 316.6 2400.0 12030
# 연속형 변수라서 확인하기 힘들어서 histogram으로 확인
welfare %>%
ggplot(aes(income)) +
geom_histogram()
# 이상치 결측 처리
welfare <- welfare %>%
mutate(income = ifelse(income %in% c(0, 9999), NA, income))
# 결측 처리 후의 income 변수 분포 확인
summary(welfare$income)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.46 123.00 193.00 242.35 316.70 2400.00 12044
# 성별 월급 평균표 만들기
sex_income <- welfare %>%
filter(!is.na(income)) %>%
group_by(sex) %>%
summarise(mean_income = mean(income))
# 시각화
sex_income %>%
ggplot(aes(sex, mean_income)) +
geom_col()
# 데이터 해석 : 평균 월급 값과 그래프를 통해서 평균적으로 남성의 월급이 여성의 두 배 가까이 된다.
# 결측치 제외 한 값들의 평균 월급에 대한 비교이므로 아래처럼 실행
welfare %>%
filter(!is.na(income)) %>% # 결측치 아닌 값들만 필터링
group_by(sex) %>% # 성별 그룹핑
summarise(mean_income = mean(income)) # 각 성별의 평균 월급
## # A tibble: 2 x 2
## sex mean_income
## <chr> <dbl>
## 1 female 163.2471
## 2 male 312.2932
welfare %>%
filter(!is.na(income)) %>% # 결측치 아닌 관측치만 필터링
ggplot(aes(sex, income)) + # 성별과 월급
geom_jitter(col = "gray") + # 관측치 분포 보기위해서
geom_boxplot(alpha = .5) # 상자를 반투명하게 출력
library(dplyr)
# 이상치 확인
summary(welfare$birth)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1907 1946 1966 1968 1988 2014
# 결측치 확인
descr::CrossTable(is.na(welfare$birth))
## Cell Contents
## |-------------------------|
## | N |
## |-------------------------|
##
## | FALSE |
## |-----------|
## | 16664 |
## |-----------|
# 파생변수 만들기 - 출생년도를 이용해서 나이 변수 추가하기
# 데이터 범위가 1900년부터 2014까지이므로 2015에서 빼는게 맞음.
# 책에 있는 코드 : welfare$age <- 2015 - welfare$birth + 1
welfare <- welfare %>%
mutate(age = 2016 - birth)
# 나이 변수 확인
summary(welfare$age)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2.00 28.00 50.00 48.43 70.00 109.00
# 나이에 따른 월급 평균표 만들기
age_income <- welfare %>%
filter(!is.na(income)) %>% # 결측치 제거
group_by(age) %>% # 나이별로 그룹핑
summarise(mean_income = mean(income)) # 요약통계량 구한 것을 최종적으로 age_income 에 저장
# 시각화 - 나이에 따른 평균 월급 추세선 그리기
age_income %>%
ggplot(aes(age, mean_income)) +
geom_line()
# 시각화 - 나이에 따른 평균 월급 산점도 그리기
welfare %>%
filter(!is.na(income)) %>% # 결측치 제거
ggplot(aes(age, income)) +
geom_point()
# 연령대 파생변수 만들기
welfare <- welfare %>%
mutate(ageg = factor(ifelse(age < 30, "young",
ifelse(age <= 59, "middle", "old")),
levels = c("young", "middle", "old")))
# 뒤에서 연령대와 평균 월급 등 작업할 때 반복적으로 levels 주기 귀찮아서 처음부터 부여함.
# 빈도수와 비율 확인
descr::CrossTable(welfare$ageg)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | young | middle | old |
## |----------|----------|----------|
## | 4334 | 6049 | 6281 |
## | 0.260 | 0.363 | 0.377 |
## |----------|----------|----------|
qplot(welfare$ageg)
# 연령대에 따른 월급차이 분석하기
# 연령대별 평균 월급표 만들기
ageg_income <- welfare %>%
filter(!is.na(income)) %>%
group_by(ageg) %>%
summarise(mean_income = mean(income))
# 연령대별 평균 월급표 시각화
ageg_income %>%
ggplot(aes(ageg, mean_income)) +
geom_col()
# 연령대 및 성별 월급 평균표 만들기
sex_income <- welfare %>%
filter(!is.na(income)) %>%
group_by(ageg, sex) %>%
summarise(mean_income = mean(income))
# 그래프 만들기 - 연령대, 성별에 따른 평균 월급 막대그래프
sex_income %>%
ggplot(aes(ageg, mean_income,
fill = sex)) +
geom_col()
# 그래프 만들기 - 남녀 따로
sex_income %>%
ggplot(aes(ageg, mean_income,
fill = sex)) +
geom_col(position = "dodge")
# 성별, 나이에 따른 평균 월급표 만들기
sex_age <- welfare %>%
filter(!is.na(income)) %>%
group_by(age, sex) %>%
summarise(mean_income = mean(income))
# 생성한 데이터 확인
glimpse(sex_age)
## Observations: 134
## Variables: 3
## $ age <dbl> 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26...
## $ sex <chr> "female", "male", "female", "male", "female", "mal...
## $ mean_income <dbl> 147.4500, 69.0000, 106.9789, 102.0500, 139.8547, 1...
# Book Code
sex_age %>%
ggplot(aes(age, mean_income,
col = sex)) +
geom_line()
# My Code
sex_age %>%
ggplot(aes(age, mean_income,
col = sex)) +
geom_jitter(col = "gray") +
geom_smooth()
## `geom_smooth()` using method = 'loess'
# 기존에 작업하던 welfare 데이터에는 직업 코드(code_job)만 존재함.
# 따라서 코드 넘버로 보기 힘든 이유로 job 변수 데이터를 welfare에 추가함.
library(readxl)
list_job <- read_excel("Koweps_Codebook.xlsx",
col_names = T,
sheet = 2)
# list_job 데이터 확인
head(list_job)
## # A tibble: 6 x 2
## code_job job
## <dbl> <chr>
## 1 111 의회의원 고위공무원 및 공공단체임원
## 2 112 기업고위임원
## 3 120 행정 및 경영지원 관리자
## 4 131 연구 교육 및 법률 관련 관리자
## 5 132 보험 및 금융 관리자
## 6 133 보건 및 사회복지 관련 관리자
glimpse(list_job)
## Observations: 149
## Variables: 2
## $ code_job <dbl> 111, 112, 120, 131, 132, 133, 134, 135, 139, 141, 149...
## $ job <chr> "의회의원 고위공무원 및 공공단체임원", "기업고위임원", "행정 및 경영지원 관리자", "연구...
# welfare 와 list_job 데이터 합치기
welfare <- welfare %>%
left_join(list_job, # 기존 welfare 데이터에 list_job 합치기
id = "code_job") # code_job을 기준으로 합침
## Joining, by = "code_job"
# 추가한 최종 데이터 확인
welfare %>%
filter(!is.na(code_job)) %>%
select(code_job, job) %>%
head(10)
## code_job job
## 1 942 경비원 및 검표원
## 2 762 전기공
## 3 530 방문 노점 및 통신 판매 관련 종사자
## 4 999 기타 서비스관련 단순 종사원
## 5 312 경영관련 사무원
## 6 254 문리 기술 및 예능 강사
## 7 510 영업 종사자
## 8 530 방문 노점 및 통신 판매 관련 종사자
## 9 286 스포츠 및 레크레이션 관련 전문가
## 10 521 매장 판매 종사자
### 분석 시작 ###
# 직업별 평균 월급표 만들기
# welfare 데이터가 data.frame 이므로 job_income 데이터도 데이터 프레임 속성을 물려받음.
job_income <- welfare %>%
filter(!is.na(job) & !is.na(income)) %>%
group_by(job) %>%
summarise(mean_income = mean(income))
# 상위 10개 직업 시각화
top10 <- job_income %>% # job_income 데이터에서
arrange(desc(mean_income)) %>% # 평균 월급을 내림차순으로 나열
head(10) # 상위 10개만 추출 후, 최종적으로 top10 에 저장
top10 %>%
ggplot(aes(reorder(job, mean_income),
mean_income)) +
geom_col() +
coord_flip()
# 상위 10개 직업 요약통계량
summary(top10)
## job mean_income
## Length:10 Min. :531.7
## Class :character 1st Qu.:551.8
## Mode :character Median :568.1
## Mean :647.6
## 3rd Qu.:744.0
## Max. :845.1
# 평균 월급 오름차순 정렬 후 하위 10개를 저장 및 출력
bottom10 <- job_income %>%
arrange(mean_income) %>%
head(10)
bottom10 %>%
ggplot(aes(reorder(job, -mean_income),
mean_income)) +
geom_col() +
coord_flip() +
ylim(0, 850) # 상위 10개 직업 요약통계량에 최댓값이 845임을 이용함.
library(gridExtra)
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
job_top <- top10 %>%
ggplot(aes(reorder(job, mean_income),
mean_income)) +
geom_col() +
coord_flip()
job_bottom <- bottom10 %>%
ggplot(aes(reorder(job, -mean_income),
mean_income)) +
geom_col() +
coord_flip() +
ylim(0, 850)
grid.arrange(job_top, job_bottom,
ncol=2)
# 1. 성별 직업 빈도표 작성하기
# 1 - 1 남성 직업 빈도 상위 10 개 추출
job_male <- welfare %>%
filter(!is.na(job) & sex == "male") %>%
group_by(job) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
head(10)
job_male
## # A tibble: 10 x 2
## job n
## <chr> <int>
## 1 작물재배 종사자 640
## 2 자동차 운전원 251
## 3 경영관련 사무원 213
## 4 영업 종사자 141
## 5 매장 판매 종사자 132
## 6 제조관련 단순 종사원 104
## 7 청소원 및 환경 미화원 97
## 8 건설 및 광업 단순 종사원 95
## 9 경비원 및 검표원 95
## 10 행정 사무원 92
# 1 - 2 여성 직업 빈도 상위 10 개 추출
job_female <- welfare %>%
filter(!is.na(job) & sex == "female") %>%
group_by(job) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
head(10)
job_female
## # A tibble: 10 x 2
## job n
## <chr> <int>
## 1 작물재배 종사자 680
## 2 청소원 및 환경 미화원 228
## 3 매장 판매 종사자 221
## 4 제조관련 단순 종사원 185
## 5 회계 및 경리 사무원 176
## 6 음식서비스 종사자 149
## 7 주방장 및 조리사 126
## 8 가사 및 육아 도우미 125
## 9 의료 복지 관련 서비스 종사자 121
## 10 음식관련 단순 종사원 104
# 2. 그래프 만들기
# 2 - 1 남성 직업 빈도 상위 10개 직업 시각화
job_male %>%
ggplot(aes(reorder(job, n),
n)) +
geom_col() +
coord_flip() # 막대그래프 전치 시키는 설정
# 2 - 2 여성 직업 빈도 상위 10개 직업 시각화
job_female %>%
ggplot(aes(reorder(job, n),
n)) +
geom_col() +
coord_flip()
library(gridExtra)
p1 <- job_male %>%
ggplot(aes(reorder(job, n),
n)) +
geom_col() +
coord_flip()
p2 <- job_female %>%
ggplot(aes(reorder(job, n),
n)) +
geom_col() +
coord_flip()
grid.arrange(p1, p2,
ncol=2)
library(descr)
# 09 - 8 - 1 종교 변수
class(welfare$religion)
## [1] "numeric"
descr::CrossTable(welfare$religion)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | 1 | 2 |
## |----------|----------|
## | 8047 | 8617 |
## | 0.483 | 0.517 |
## |----------|----------|
# 1 == 종교 있음 / 2 == 무교 / 3 == 모름 or 무응답
## 책에서는 종교의 유무만 factor로 변환했는데 3번이라 답한것도 업다고 변환함.
## 3이라고 응답한 변수에 대해서는 No 라고 하기보다 아예 결측치로 처리해도 될듯함.
# religion 변수 전처리 - 책에 있는 코드
# welfare$religion <- ifelse(welfare$religion == 1, "Yes", "No")
# My code
welfare <- welfare %>%
mutate(religion = ifelse(religion == 1, "Yes", "No"))
# 전처리한 종교 변수 확인
glimpse(welfare$religion)
## chr [1:16664] "No" "No" "No" "Yes" "Yes" "Yes" "Yes" "Yes" "Yes" ...
descr::CrossTable(welfare$religion)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | No | Yes |
## |----------|----------|
## | 8617 | 8047 |
## | 0.517 | 0.483 |
## |----------|----------|
# 09 - 8 - 2 혼인 변수
# 파생변수로 이혼 변수를 만드는 과정이다.
# marriage 변수에는 0부터 6까지 6가지 경우인데,
# 그중에 혼인과 이혼만 factor 변수로 부여하고 그 외에는 결측처리 한다.
welfare <- welfare %>%
mutate(group_marriage = ifelse(welfare$marriage == 1, "marriage",
ifelse(welfare$marriage == 3, "divorce", NA)))
# 혼인 변수 빈도수 확인
CrossTable(welfare$group_marriage)
## Cell Contents
## |-------------------------|
## | N |
## | N / Row Total |
## |-------------------------|
##
## | divorce | marriage |
## |----------|----------|
## | 712 | 8431 |
## | 0.078 | 0.922 |
## |----------|----------|
qplot(welfare$group_marriage)
# 09 - 8 - 3 종교 유무에 따른 이혼율 표 만들기
religion_marriage <- welfare %>%
filter(!is.na(group_marriage)) %>%
group_by(religion, group_marriage) %>%
summarise(n = n()) %>%
mutate(pct = round(n/sum(n)*100, 1))
religion_marriage
## # A tibble: 4 x 4
## # Groups: religion [2]
## religion group_marriage n pct
## <chr> <chr> <int> <dbl>
## 1 No divorce 384 8.3
## 2 No marriage 4218 91.7
## 3 Yes divorce 328 7.2
## 4 Yes marriage 4213 92.8
# 앞서 만든 religion_marriage data 에서 이혼에 해당하는 data만 추출
divorce <- religion_marriage %>%
filter(group_marriage == "divorce") %>%
select(religion, pct)
divorce
## # A tibble: 2 x 2
## # Groups: religion [2]
## religion pct
## <chr> <dbl>
## 1 No 8.3
## 2 Yes 7.2
# 이혼한 대상 시각화 - 막대 그래프
divorce %>%
ggplot(aes(religion, pct)) +
geom_col()
# 연령대 및 종교 유무에 따른 이혼율 분석하기
# - 이혼에 연령과 종교유무가 연관이 있는지 관찰하는 과정
# 1. 연령대별 이혼율 표 만들기
ageg_marriage <- welfare %>%
filter(!is.na(group_marriage)) %>% # 결측치 필터링
group_by(ageg, group_marriage) %>% # ageg == 연령대
summarise(n = n()) %>% # 각 그룹별 관측치 갯수 파악
mutate(pct = round(n/sum(n)*100, 1)) # pct == percent : 비율
ageg_marriage
## # A tibble: 6 x 4
## # Groups: ageg [3]
## ageg group_marriage n pct
## <fctr> <chr> <int> <dbl>
## 1 young divorce 2 3.3
## 2 young marriage 58 96.7
## 3 middle divorce 437 8.9
## 4 middle marriage 4481 91.1
## 5 old divorce 273 6.6
## 6 old marriage 3892 93.4
# 연령대별 이혼율 그래프 만들기
ageg_divorce <- ageg_marriage %>%
filter(ageg != "young" & group_marriage == "divorce") %>%
select(ageg, pct)
ageg_divorce
## # A tibble: 2 x 2
## # Groups: ageg [2]
## ageg pct
## <fctr> <dbl>
## 1 middle 8.9
## 2 old 6.6
ageg_divorce %>%
ggplot(aes(ageg, pct)) +
geom_col()
# 연령대, 종교 유무, 결혼 상태별 비율표 만들기
ageg_religion_marriage <- welfare %>%
filter(!is.na(group_marriage) & ageg != "young") %>%
group_by(ageg, religion, group_marriage) %>%
summarise(n = n()) %>%
mutate(pct = round(n/sum(n)*100, 1))
# 연령대 및 종교 유무별 이혼율 표 만들기
df_divorce <- ageg_religion_marriage %>%
filter(group_marriage == "divorce") %>%
select(ageg, religion, pct)
df_divorce
## # A tibble: 4 x 3
## # Groups: ageg, religion [4]
## ageg religion pct
## <fctr> <chr> <dbl>
## 1 middle No 9.7
## 2 middle Yes 7.9
## 3 old No 6.5
## 4 old Yes 6.6
# 연령대 및 종교 유무에 따른 이혼율 그래프 만들기
df_divorce %>%
ggplot(aes(ageg, pct,
fill = religion)) +
geom_col(position = "dodge")
# 변수 검토 생략
# 전처리 - 지역 코드 목록 만들기
list_region <- data.frame(code_region = c(1:7),
region = c("서울",
"수도권(인천/경기)",
"부산/경남/울산",
"대구/경북",
"대전/충남",
"강원/충북",
"광주/전남/전북/제주도"))
list_region
## code_region region
## 1 1 서울
## 2 2 수도권(인천/경기)
## 3 3 부산/경남/울산
## 4 4 대구/경북
## 5 5 대전/충남
## 6 6 강원/충북
## 7 7 광주/전남/전북/제주도
# 기존 데이터에 새로 생성한 지역 변수 추가하기
welfare <- welfare %>%
left_join(list_region,
id = "code_region")
## Joining, by = "code_region"
welfare %>%
select(code_region, region) %>%
head()
## code_region region
## 1 1 서울
## 2 1 서울
## 3 1 서울
## 4 1 서울
## 5 1 서울
## 6 1 서울
# 지역별 연령대 비율 분석하기
# 지역별 연령대 비율표 만들기
region_ageg <- welfare %>%
group_by(region, ageg) %>%
summarise(n = n()) %>%
mutate(pct = round(n/sum(n)*100, 2))
# 그래프 그리기
region_ageg %>%
ggplot(aes(region, pct,
fill = ageg)) +
geom_col() +
coord_flip()
# 노년층 비율 높은 순으로 막대 정렬하기
list_order_old <- region_ageg %>%
filter(ageg == "old") %>%
arrange(pct)
order <- list_order_old$region
region_ageg %>%
ggplot(aes(region, pct,
fill = ageg)) +
geom_col() +
coord_flip() +
scale_x_discrete(limits = order)
# 필요한 패키지 장착
library(KoNLP)
## Checking user defined dictionary!
library(dplyr)
library(stringr)
library(rJava)
library(memoise)
# 사용할 언어 사전 설정
useNIADic()
## Backup was just finished!
## 983012 words dictionary was built.
# Sejong 사전도 있지만 등록되어있는 단어 수의 차이가 심함.
# 만약 사용한다면 useSejongDic() 으로 설정해주면 된다.
txt <- readLines("hiphop.txt")
## Warning in readLines("hiphop.txt"): 'hiphop.txt'에서 불완전한 마지막 행이
## 발견되었습니다
head(txt)
## [1] "\"보고 싶다" "이렇게 말하니까 더 보고 싶다"
## [3] "너희 사진을 보고 있어도" "보고 싶다"
## [5] "너무 야속한 시간" "나는 우리가 밉다"
# 특수문자 제거하기
txt <- stringr::str_replace_all(txt,
"\\W", " ")
# "\\W" 는 정규표현식의 하나
# str_replace_all 은 base::gsub() 혹은 replace 와 동일한 기능으로써
# 해당 데이터 내의 문자열을 치환하는 것이다.
# 노래 가사에서 명사 추출
nouns <- KoNLP::extractNoun(txt)
# 추출한 명사 List를 문자열 벡터로 변환, 단어별 빈도표 생성하기
wordcount <- table(unlist(nouns))
# Data Frame 으로 변환하기
df_word <- as.data.frame(wordcount,
stringsAsFactors = F)
# 변수명 수정하기
df_word <- df_word %>%
rename(word = Var1,
freq = Freq)
# 자주 사용된 단어 빈도표 만들기
# 두 글자 이상 단어 추출
df_word <- df_word %>%
filter(nchar(word) >= 2)
# 빈도 순으로 정렬한 후 상위 20개 단어 추출
top_20 <- df_word %>%
arrange(desc(freq)) %>%
head(20)
# 시각화 - Word Cloud
# 패키지 장착
library(wordcloud)
## Loading required package: RColorBrewer
library(RColorBrewer)
# 색상 목록 및 그 내부에서 사용할 색상까지 고정해서 시각화하기
pal <- RColorBrewer::brewer.pal(8, "Blues")[5:9]
set.seed(0115)
# 0115번 워드 클라우드 - 즉 워드 클라우드에 네이밍하는 거라고 보면 됨.
wordcloud(words = df_word$word, # 단어
freq = df_word$freq, # 빈도
min.freq = 2, # 최소 단어 빈도
max.words = 200, # 최대 시각화 할 단어 수
random.order = F, # 고빈도 단어 중앙배치 (F : 중앙배치 / T : 랜덤배치)
rot.per = .1, # 회전 단어 비율
scale = c(4, .3), # 단어 크기 범위
colors = pal) # 색상 목록
library(dplyr)
twitter <- read.csv("twitter.csv",
header = T,
stringsAsFactors = F,
fileEncoding = "UTF-8")
# 전처리 - 뒤에 데이터 프레임 변환하는 과정을 선행해서 함.
twitter <- twitter %>%
rename(no = 번호,
id = 계정이름,
date = 작성일,
tw = 내용)
twitter <- str_replace_all(twitter$tw,
"\\W", " ")
head(twitter)
## [1] "민주당의 ISD관련 주장이 전부 거짓으로 속속 드러나고있다 미국이 ISD를 장악하고 있다고 주장하지만 중재인 123명 가운데 미국인은 10명뿐이라고 한다 "
## [2] "말로만 미제타도 사실은 미제환장 김정일 운구차가 링컨 컨티넬탈이던데 북한의 독재자나 우리나라 종북들이나 겉으로는 노동자 서민을 대변한다면서 고급 외제차 아이팟에 자식들 미국 유학에 환장하는 위선자들인거죠"
## [3] "한나라당이 보수를 버린다네요 뭔가착각하는모냥인에 국민들이보수를싫어하는게 아니라뻘짓거리하는분들을싫어하는겁니다야당이진보어쩌고저쩌고한다고해서그들을조아한다고생각하면대착각"
## [4] "FTA를 대하는 현명한 자세 사실 자유주의 경제의 가장 큰 수해자는 한국이죠 농어업분야 피해를 줄이는 정부대안을 최대한 보완하고 일자리 창출 등 실익을 최대화해 나가는게 현실적인 대처자세일듯 "
## [5] "곽노현씨 갈수록 가관입니다 뇌물질에 아들 병역 의혹까지 도대체 아이들이 뮐 보고 배우겠습니까 이래도 자리 연연하시겠습니까 "
## [6] "과거 집권시 한미FTA를 적극 추진하던 세력이 이제 집권하면 폐기하겠다고 주장합니다 어이없어 말도 안 나오네요 표만 얻을 수 있다면 국가 안보나 경제가 어떻게 되든 상관없다는 무책임한 행태들 우리 정치의 후진성을 드러내는 거죠 "
# 명사 추출
nouns_twitter <- extractNoun(twitter)
class(twitter)
## [1] "character"
# 추출한 명사 list 를 문자열 벡터로 변환, 단어별 빈도표 생성
wordcount_twitter <- table(unlist(nouns_twitter))
df_word_twitter <- as.data.frame(wordcount_twitter,
stringsAsFactors = F)
# 변수명 수정
df_word_twitter <- rename(df_word_twitter,
word = Var1,
freq = Freq)
# 두 글자 이상만 추출하게 조건 제한
df_word_twitter <- filter(df_word_twitter,
nchar(word) >= 2)
# 상위 20개 추출
top_20_twitter <- df_word_twitter %>%
arrange(desc(freq)) %>%
head(20)
library(wordcloud)
library(RColorBrewer)
pal <- RColorBrewer::brewer.pal(8, "Blues")[5:9]
set.seed(123) # 123번 워드 클라우드 - 즉 워드 클라우드에 네이밍하는 거라고 보면 됨.
wordcloud(words = df_word_twitter$word, # 단어
freq = df_word_twitter$freq, # 빈도
min.freq = 10, # 최소 단어 빈도
max.words = 200, # 최대 시각화 할 단어 수
random.order = F, # 고빈도 단어 중앙배치 (F : 중앙배치 / T : 랜덤배치)
rot.per = .1, # 회전 단어 비율
scale = c(4, .5), # 단어 크기 범위
colors = pal) # 색상 목록