27. ggplot2 패키지와 wordcloud2


r

Overview

R에서 ggplot2 패키지와 wordcloud2를 이용한 시각화 방법을 알아본다.


예제 1

library(rJava)
library(KoNLP)
library(stringr)
library(dplyr)
library(ggplot2)
library(extrafont)
library(RColorBrewer)
library(wordcloud2)

# font_import()
theme_set(theme_gray(base_family = 'D2Coding'))

cleaner <- function(x) {
  # res <- str_extract_all(x, '\\w{2,}')
  res <- str_replace_all(x, '\\W', ' ')
  return(res)
}

twit <- read.csv('twitter.csv', header = T, fileEncoding = 'UTF-8')
twit

colnames(twit) <- c('x', 'no', 'id', 'regdate', 'contents')
head(twit)

head(twit$contents)

twit$contents <- cleaner(twit$contents)
twit$contents

# 명사 추출
buildDictionary(ext_dic = c('sejong', 'woorimalsam'))
nouns <- extractNoun(twit$contents)
# nounsS <- SimplePos22(twit$contents)
# nounsM <- MorphAnalyzer(twit$contents)
nounsM


# nouns 는 리스트로 반환되므로 unlist로 벡터화 시킨다.
wordcount <- table(unlist(nouns))

newFrame <- as.data.frame(wordcount, stringaAsFactor = F)
newFrame

newFrame <- rename(newFrame, word = Var1, freq = Freq)
colnames(newFrame)

# 음절이 2글자 이상인 단어만 추출
class(newFrame$word)
newFrame$word <- as.vector(newFrame$word)
newFrame <- filter(newFrame, nchar(word) >= 2)
newFrame

top20 <- newFrame %>% arrange(desc(freq)) %>% head(20)
top20

ordering <- arrange(top20, freq)$word
ordering

# ggplot 사용 옵션 확인
# aes : aesthetics
# fill, color옵션이 색상을 결정
# geom_col : 막대 그래프를 그려주는 옵션
# 기본 값으로 누적된 그래프를 그려주며 요약된 표를 이용하여 막대그래프를 그릴때 사용
# coord_flip() : horiz 옵션과 동일
# theme_bw(base_family = 'D2Coding') : 폰트 문제 해결
# theme 은 다양함
# scale_x_discrete(limit = ordering) : 내림차순
ggplot(data = top20, aes(x = word, y = freq, fill = word, color = word)) + ylim(0, max(top20$freq + 100)) + geom_col() + coord_flip() + scale_x_discrete(limit = ordering) + geom_text(aes(label = freq), hjust = -0.3) + theme_bw(base_family = 'D2Coding')

# 색상 팔레트
# 팔레트를 불러와서 슬라이싱 가능
display.brewer.all()
pallette1 <- brewer.pal(8, 'Dark2')
pallette2 <- brewer.pal(9, 'Blues')[5:9]

top100 <- newFrame %>% arrange(desc(freq)) %>% head(100)
wordcloud2(top100, fontFamily = 'D2Coding', rotateRatio = 0, shuffle = T, size = 1.5, color = pallette2)

예제 2

library(rJava)
library(KoNLP)
library(stringr)
library(dplyr)
library(ggplot2)
library(extrafont)
library(RColorBrewer)
library(wordcloud2)

cleaner <- function(x) {
  res <- str_replace_all(x, '\\W', ' ')
  return(res)
}

cleaner2 <- function(x) {
  res <- str_extract(x, "[가-힣]{2,6}")
  res <- str_replace(res, '\\.', '')
  res <- str_replace(res, '\\n', '')
  res <- str_replace(res, '\\d+', '')
  return(res)
}

# text line을 읽어들이는 함수 
data01 <- readLines('propose.txt')
data01

buildDictionary(ext_dic = c('sejong', 'woorimalsam'))
data02 <- sapply(data01, extractNoun)
data02

data03 <- unlist(data02)
data03

length(data03)

data04 <- cleaner2(data03)
data04

stopwords <- readLines('propose_gsub.txt')

for(idx in 1:length(stopwords)) {
  data04 <- gsub(stopwords[idx], '', data04)
}
data04

data04 <- Filter(function(x) {nchar(x) >= 2}, data04)
data04 <- Filter(function(x) {nchar(x) <= 6}, data04)
data04

head(unlist(data04), 20)

newData <- unlist(data04)
newData

wordcount <- table(newData)
wordcount <- sort(wordcount, decreasing = T)

chartdata <- head(wordcount, 10)
mColor <- rainbow(length(chartdata))

df <- as.data.frame(chartdata)
colnames(df) <- c('내용', '빈도수')

df
ggplot(data = df, aes(x = 내용, y = 빈도수, fill = 내용, color = 내용)) + ylim(0, max(df$빈도수 + 5)) + geom_col() + coord_flip() + geom_text(aes(label = 빈도수), hjust = -0.3) + theme_bw(base_family = 'D2Coding') + labs(title = 'Propose Present Top 10')

wordcount <- table(newData)
wordcount <- head(sort(wordcount, decreasing = T), 100)
mColor2 <- brewer.pal(10, 'Set1')

wordcloud2(wordcount, fontFamily = 'D2Coding', rotateRatio = 0, shuffle = T, size = 1.5, color = mColor2)

예제 3

library(rJava)
library(KoNLP)
library(stringr)
library(dplyr)
library(ggplot2)
library(extrafont)
library(RColorBrewer)
library(wordcloud2)

fileName <- 'Untitled spreadsheet - ExcelData.csv'
data01 <- read.csv(fileName, header = T)
data01

dustData <- data01[c(1:3)]
dustData

# 필터링
dustData_an <- dustData %>% filter(측정소명 %in% c('강동구', '송파구'))
dustData_an

# 날짜별 카운트
count(dustData_an, date) %>% arrange(desc(n))
# 측정소 별 카운트
count(dustData_an, 측정소명) %>% arrange(desc(n))

# 측정소 별로 분리하기
gangdong <- subset(dustData_an, 측정소명 == '강동구')
songpa <- subset(dustData_an, 측정소명 == '송파구')

summary(gangdong$미세먼지)
summary(songpa$미세먼지)

# theory : 두 지역의 평균은 차이가 없다.
# p-value > 0.05 이면 가설을 채택
# t 검증 : 두 집단의 평균이 같은지를 판단할 때 사용
t.test(data = dustData_an, 미세먼지 ~ 측정소명)
#
# Welch Two Sample t-test
# 
# data:  미세먼지 by 측정소명
# t = 1.0225, df = 706.39, p-value = 0.3069
# alternative hypothesis: true difference in means is not equal to 0
# 95 percent confidence interval:
#   -1.796001  5.699641
# sample estimates:
#   mean in group 강동구 mean in group 송파구 
# 44.05753             42.10571 

par(family = 'D2Coding')
boxplot(gangdong$미세먼지, songpa$미세먼지, names = c('강동구', '송파구'), col = rainbow(2))


예제 4

# install.packages('twitteR')
library(twitteR)
library(stringr)

# API 인증을 위한 변수 목록 셋팅
# https://developer.twitter.com/en/app
apiKey <-  "****" 
apiSecret <- "****" 
accessToken="****-****"
accessTokenSecret="****"

setup_twitter_oauth(consumer_key = apiKey, consumer_secret = apiSecret, access_token = accessToken, access_secret = accessTokenSecret)

# [1] "Using direct authentication"
# Use a local file ('.httr-oauth'), to cache OAuth access credentials between R sessions?
# 의 형식으로 물어 보는 데, 로컬 캐싱 내용을 사용할 것인가를 물어 보는 것이다.
# 2를 눌러서 새로운 인증을 시도로 하도록 한다.

searchWord <- 'London'
keyword <- enc2utf8( searchWord ) # base 패키지에 있음(인코딩 함수)
keyword

# Warning message:
#   In doRppAPICall("search/tweets", n, params = params, retryOnRateLimit = retryOnRateLimit,  :
#                     300 tweets were requested but the API can only return 42
searchResult <- searchTwitter(searchString = keyword, n = 300, lang = 'ko') #300개

class(searchResult) # "list"

tw_result <- twListToDF(searchResult)
head(tw_result, 2)

str(tw_result)

# 저장할 파일 이름
filename = paste('twitter(', searchWord ,').txt', sep='')
write.csv(tw_result, filename, quote = F, row.names = F)

# 텍스트, 생성횟수, 리트윗 횟수, 위치 정보 등등
colnames(tw_result)

bigdata_text <- tw_result$text
head(bigdata_text)

# install.packages('KoNLP')
library(KoNLP)
useSejongDic()
# buildDictionary(ext_dic = c('sejong', 'woorimalsam'))

# 명사 추출 후 list를 vector으로 변환한다.
bigdata_noun <- sapply(bigdata_text, extractNoun, USE.NAMES = F)
bigdata_noun <- unlist(bigdata_noun)
bigdata_noun
length(bigdata_noun)

# 2글자 이상만 추출하기
bigdata_noun <- Filter(function(x){ nchar(x) >= 2}, bigdata_noun)

# 참고로 gsub 대신에 정규 표현식을 사용해도 된다.
# bigdata_noun <- gsub('[A-Za-z0-9]', '', bigdata_noun) # 영어와 숫자 제거
# bigdata_noun <- gsub('[~!@#$%^&*()/_+|?:;]', '', bigdata_noun) # 특수 문자 제거
# bigdata_noun <- gsub('[ㄱ-ㅎ]', '', bigdata_noun) # 자음 제거
# bigdata_noun <- gsub('[ㅜ|ㅠ]', '', bigdata_noun) #1개 이상의 ㅜ와 ㅠ를 제거
bigdata_noun <- str_extract(bigdata_noun, '[A-z]{3,}')
bigdata_noun <- gsub(keyword, '', bigdata_noun) # keyword 제거

word_table <- table(bigdata_noun)
tmp <- sort(word_table, decreasing = T)
# for (idx in 1:6) {
#   if(tmp[idx] > 200) {
#     tmp[idx] <- tmp[idx] - 100
#   } else {
#     tmp[idx] <- tmp[idx] - 30
#   }
# }
head(tmp)
word_table <- sort(tmp, decreasing = T)

# install.packages('wordcloud2')
library(wordcloud2)

wordcloud2(data = tmp, fontFamily = 'Nanum Gothic', size = 10, color = 'random-light', backgroundColor = 'black') + WCtheme(1)





© 2019. by RaP0d

Powered by aiden