민주당 문재인 후보와 국민의당 안철수 후보가 양강 체계를 구축하고 치열한 각축전을 벌이고 있다. 심상정 후보는 페이스북을 통해 지지세를 넓혀가고 있고, 홍준표와 유승민 후보는 페북이 유의미한 숫자를 만들어 내고 있지는 않다. 페이스북 팬수 추세를 시각화 한다.
TV 토론이 지지율에 미치는 효과를 검증하기 위한 도구로 페이스북 페이지 팬수 증가분을 통계지표로 삼는다.
심상정 후보는 JTBC TV토론을 비롯한 5차례 TV토론 효과를 가장 많이 본 것으로 보이며 안철수 후보는 TV토론에서 초반에 열세를 보였지만, 후반에는 신속한 학습능력을 통해 만회를 한 것으로 보인다.
# 0. 참고문헌 ---------------------------------------------------------------------
library(Rfacebook)
library(RCurl)
library(tidyverse)
library(lubridate)
library(ggplot2)
library(stringr)
library(DT)
library(gridExtra)
library(ggthemes)
library(extrafont)
loadfonts()
fb_keys <- "EAACEdEose0cBAHWKOFk58ltUcZBvzFH5d6HYFDGD17iMC7ZALo5sxuU8WgYVX55FMYL3bslRhcKUWEwxacHVKDjgq7d2edjSBTUVUcQmkVtJOc9pldZCO9ZABhKCiiQ3nc2gjYHzgeZCbCZB5N7gceefKZASqVZBEbCHQNZAlc1TRlAzxsAIiV86v"
fb_crawl_date <- "2017-05-03"
# 1. 데이터 불러오기 ---------------------------------------------------------------------
## 1.1. 페북 데이터 데이터---------------------------------
get_fb_likes <- function(fb_pages, sdate, edate, fb_keys){
url <- paste0("https://graph.facebook.com/v2.8/", fb_pages, "/insights/page_fans_country/lifetime?&since=", sdate, "&until=", edate, "&access_token=", fb_keys)
url_json <- getURL(url)
url_list <- fromJSON(url_json)
url_dat_likes <- lapply(url_list$data[[1]]$values, function(x) {x$value})
library(gtools)
url_dat_df <- do.call(gtools::smartbind, url_dat_likes)
url_dat_df[is.na(url_dat_df)] <- 0
url_date <- lapply(url_list$data[[1]]$values, function(x) {x$end_time})
url_date_df <- do.call(rbind, url_date)
url_df <- cbind(url_date_df, url_dat_df)
url_df <- url_df %>%
dplyr::mutate(url_date_df = lubridate::ymd(stringr::str_sub(url_date_df, 1, 10))) %>%
dplyr::rename(fdate=url_date_df)
return(url_df)
}
# 2. 데이터 가져오기 ---------------------------------------------------------------
## 2.1. 안철수
ahn_fan_1703 <- get_fb_likes("ahncs111", "2017-01-01", "2017-03-30", fb_keys)
ahn_fan_1704 <- get_fb_likes("ahncs111", "2017-03-30", fb_crawl_date, fb_keys)
ahn_fan <- bind_rows(ahn_fan_1703, ahn_fan_1704)
ahn_fan_lng <- ahn_fan %>%
gather(`iso-a2`, fans, -fdate) %>%
mutate(fans = ifelse(is.na(fans), 0, fans))
ahn_fan_lng <- ahn_fan_lng %>%
group_by(fdate) %>%
dplyr::summarise(ahn_fans = sum(fans))
write_csv(ahn_fan_lng, "data/fb_ahn.csv")
## 2.2. 문재인
moon_fan_1703 <- get_fb_likes("moonbyun1", "2017-01-01", "2017-03-30", fb_keys)
moon_fan_1704 <- get_fb_likes("moonbyun1", "2017-03-30", fb_crawl_date, fb_keys)
moon_fan <- bind_rows(moon_fan_1703, moon_fan_1704)
moon_fan_lng <- moon_fan %>%
gather(`iso-a2`, fans, -fdate) %>%
mutate(fans = ifelse(is.na(fans), 0, fans))
moon_fan_lng <- moon_fan_lng %>%
group_by(fdate) %>%
dplyr::summarise(moon_fans = sum(fans))
write_csv(moon_fan_lng, "data/fb_moon.csv")
## 2.3. 심상정
sim_fan_1703 <- get_fb_likes("simsangjung", "2017-01-01", "2017-03-30", fb_keys)
sim_fan_1704 <- get_fb_likes("simsangjung", "2017-03-30", fb_crawl_date, fb_keys)
sim_fan <- bind_rows(sim_fan_1703, sim_fan_1704)
sim_fan_lng <- sim_fan %>%
gather(`iso-a2`, fans, -fdate) %>%
mutate(fans = ifelse(is.na(fans), 0, fans))
sim_fan_lng <- sim_fan_lng %>%
group_by(fdate) %>%
dplyr::summarise(sim_fans = sum(fans))
write_csv(sim_fan_lng, "data/fb_sim.csv")
## 2.4. 데이터 정제 ---------------------------------------------------------------
moon_df <- read_csv("data/fb_moon.csv")
ahn_df <- read_csv("data/fb_ahn.csv")
sim_df <- read_csv("data/fb_sim.csv")
fb_fans_df <- moon_df %>%
left_join(ahn_df, by="fdate") %>%
left_join(sim_df, by="fdate")
fb_fans_long_df <- fb_fans_df %>%
gather(candidate, fans, -fdate) %>%
mutate(candidate = factor(candidate, levels=c("moon_fans", "sim_fans", "ahn_fans")))
DT::datatable(fb_fans_df) %>%
DT::formatCurrency(c(2,3,4), '', mark=",", digits=0)
ggsave()
함수로 그래프 시각화 산출물을 저장할 경우 가장 마지막 그래프만 자동으로 저장한다. Saving grid.arrange() plot to file을 참조하면 그런 문제를 해결할 수 있다. 즉 grid.arrange
대신 arrangeGrob
함수를 사용하면 원하는 방식으로 그래프를 저장할 수 있다.
# 3. 데이터 시각화 ---------------------------------------------------
## 3.1. 전체 후보 ----------------------------------------------------
fans_p <- fb_fans_long_df %>%
ggplot() +
aes(x=fdate, y=fans, fill=candidate, color=candidate) +
geom_line(size=1.7) +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="Facebook Fans Trend",
caption="\n 출처: Facebok for Developers, Graph API Explorer") +
theme(legend.position="top") +
scale_colour_manual(name="",
values=c(moon_fans="#065ce8",
ahn_fans="#07f91f",
sim_fans="#f2ee09")) +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="red", size=0.9)
grid.arrange(fans_p, nrow=1)
## 3.2. 후보 별로 ----------------------------------------------------
ahn_p1 <- ahn_df %>%
ggplot(aes(x= fdate, y=ahn_fans/1000)) +
geom_line(colour="#07f91f") +
geom_point(size=1.3, colour="#07f91f") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="안철수 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(ahncs111)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="red", size=0.9)
moon_p1 <- moon_df %>%
ggplot(aes(x= fdate, y=moon_fans/1000)) +
geom_line(colour="#065ce8") +
geom_point(size=1.3, colour="#065ce8") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="문재인 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(moonbyun1)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="red", size=0.9)
sim_p1 <- sim_df %>%
ggplot(aes(x= fdate, y=sim_fans/1000)) +
geom_line(colour="#f2ee09") +
geom_point(size=1.3, colour="#f2ee09") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="심상정 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(simsangjung)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="red", size=0.9) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="red", size=0.9)
grid.arrange(moon_p1, sim_p1, ahn_p1, nrow=1)
## 3.3. 후보 별로 확대 ----------------------------------------------------
ahn_p2 <- ahn_df %>% dplyr::filter(fdate >="2017-04-01") %>%
ggplot(aes(x= fdate, y=ahn_fans)) +
geom_line(colour="#07f91f") +
geom_point(size=1.7, colour="#07f91f") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="안철수 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(ahncs111)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="#ab3ae8", size=0.3) +
annotate(geom="text",x=as.Date("2017-04-19"), y=105000,label="KBS",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-23"), y=116000,label="1차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-25"), y=105000,label="JTBC",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-28"), y=116000,label="2차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-05-02"), y=105000,label="3차",fontface="bold", size=3)
moon_p2 <- moon_df %>% dplyr::filter(fdate >="2017-04-01") %>%
ggplot(aes(x= fdate, y=moon_fans)) +
geom_line(colour="#065ce8") +
geom_point(size=1.7, colour="#065ce8") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="문재인 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(moonbyun1)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="#ab3ae8", size=0.3) +
annotate(geom="text",x=as.Date("2017-04-19"), y=492000,label="KBS",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-23"), y=502000,label="1차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-25"), y=492000,label="JTBC",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-28"), y=502000,label="2차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-05-02"), y=492000,label="3차",fontface="bold", size=3)
sim_p2 <- sim_df %>% dplyr::filter(fdate >="2017-04-01") %>%
ggplot(aes(x= fdate, y=sim_fans)) +
geom_line(colour="#f2ee09") +
geom_point(size=1.7, colour="#f2ee09") +
scale_x_date(date_labels = "%m-%d") +
scale_y_continuous(labels=scales::comma) +
# theme_minimal(base_family="NanumGothic") +
labs(x="",y="",title="심상정 페이스북 페이지 팬 추세",
caption="\n 출처: 페이스북 페이지(simsangjung)") +
theme(legend.position="none") +
geom_vline(xintercept=as.numeric(ymd("2017-04-19")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-23")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-25")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-04-28")), linetype=4, color="#ab3ae8", size=0.3) +
geom_vline(xintercept=as.numeric(ymd("2017-05-02")), linetype=4, color="#ab3ae8", size=0.3) +
annotate(geom="text",x=as.Date("2017-04-19"), y=245000,label="KBS",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-23"), y=230000,label="1차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-25"), y=245000,label="JTBC",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-04-28"), y=230000,label="2차",fontface="bold", size=3) +
annotate(geom="text",x=as.Date("2017-05-02"), y=245000,label="3차",fontface="bold", size=3)
grid.arrange(moon_p2, sim_p2, ahn_p2, nrow=1)