[R] Do It R 7편 지도와 인터랙티브 그래프
카테고리: R
💡 R을 처음 배우기 위해 공부한 책입니다.
책에서 공부한 내용을 정리하고, 이를 기반으로 직접 문제를 만들어 풀이해보는 식으로 학습했습니다.
KBO, MLB 야구 기록들을 csv 파일로 크롤링하여 문제에 사용했고,
야구 데이터 패키지인 Lahman
을 토대로 문제를 만들기도 했습니다.
책 소개
11. 지도 시각화
11-1. 미국 주별 강력 범죄율 단계 구분도
지역별 통계치를 색깔의 차이로 표현한 지도를 단계구분도(Choropleth Map)이라 한다. 미국 주별 강력 범죄율 데이터를 이용해 단계구분도를 만들어보자. 단계구분도는 ggiraphExtra
패키지로 만들 수 있는데, 그 전에 먼저 mapproj
패키지를 설치해야 한다.
USArrests
데이터는 1973년 미국 주별 강력 범죄율 정보를 담고 있다. 이 데이터는 지역명 변수가 따로 없기 때문에 tibble
패키지의 rownames_to_column()
함수로 행 이름을 state 변수로 바꿔 새 데이터프레임으로 만들어야 한다.
뒤에 사용할 지도 데이터의 지역명 변수는 모두 소문자이기에 이에 맞춰주기 위해 state
값을 tolower()
로 소문자로 만든다.
install.packages("mapproj")
install.packages("ggiraphExtra")
library(ggiraphExtra)
str(USArrests)
library(tibble)
crime <- rownames_to_column(USArrests, var="state")
crime$state <- tolower(crime$state)
단계구분도를 만들려면 지역별 위도, 경도 정보가 있는 maps 패키지가 필요하다. 그리고 패키지의 map_data()
를 이용해 이 데이터를 데이터 프레임으로 불러온다.
install.packages("maps")
library(ggplot2)
states_map <- map_data("state")
이제 데이터가 모두 준비되었으니 ggChoropleth()
함수로 단계 구분도를 만들어보자. 살인 범죄 건수를 색깔로 표현하기 위해 fill
매개변수를 Murder
로 지정하고, map_id
에 지역 구분 기준이 되는 state
를 지정한다. map
매개변수에는 앞서 만든 지도 데이터프레임 states_map
을 넣는다.
ggChoropleth(data=crime, aes(fill=Murder, map_id=state), map=states_map)
만약 interactive
파라미터를 TRUE로 설정하면, 마우스 움직임에 반응하는 인터랙티브 단계 구분도를 만들 수 있다.
ggChoropleth(data=crime, aes(fill=Rape, map_id=state), map=states_map, interactive = T)
11-2. 대한민국 시도별 인구, 결핵 환자 수 단계 구분도 만들기
kormaps2014
패키지를 이용하면 대한민국의 지역 통계 데이터와 지도 데이터를 사용할 수 있다.
패키지가 설치되지 않는 관계로 생략한다.
12. 인터랙티브 그래프
인터랙티브 그래프(Interactive Graph)란 마우스 움직임에 반응하며 실시간으로 형태가 변하는 그래프이다. 그래프를 HTML 포맷으로 저장하면 일반 사용자들도 웹 브라우저에서 그래프를 조작할 수 있다.
ggplot()
으로 만든 그래프에 ggplotly()
를 적용하면 인터랙티브 그래프가 만들어진다.
install.packages("plotly")
library(plotly)
install.packages("ggplot2")
library(ggplot2)
p <- ggplot(data=mpg, aes(x=displ, y=hwy, col=drv))+geom_point()
ggplotly(p)
점 위에 마우스 커서를 갖다대면 값이 나타나고, 특정 부분을 드래그하면 그 영역을 확대할 수 있다.
뷰어 창에서 Export → Save as Web Page를 클릭하면 그래프를 HTML 포맷으로 저장할 수 있다. 이 파일은 R을 사용하지 않아도 웹에서 열어볼 수 있다.
❓ 문제.
2019년 메이저리그 포지션별 홈런 수를 인터랙티브 그래프로 나타내보자.
💡 정답.
batting_2019 <- Batting %>%
filter(yearID==2019)
fielding_2019 <- Fielding %>%
filter(yearID==2019)
POSHR <- ggplot(data=poshr, aes(x=POS, y=HR, fill=POS)) + geom_col()
ggplotly(POSHR)
이번엔 dygraphs
패키지로 인터랙티브 시계열 그래프를 만들어보자.
시계열 그래프를 만들려면 xts()
를 이용해 데이터를 시간 순서 속성을 갖게 해야 한다.
install.packages("dygraphs")
library(dygraphs)
library(xts)
economics <- ggplot2::economics
eco <- xts(economics$unemploy, order.by=economics$date)
dygraph(eco)
dyRangeSelector()
를 추가하면 그래프 아래에 날짜 범위 선택 기능이 추가된다.
dygraph(eco) %>% dyRangeSelector()
여러 값을 동시에 표현할 수도 있다. economics
데이터의 unemploy
와 psavert
를 함께 표현해보자.
ecoa <- xts(economics$psavert, order.by=economics$date)
ecob <- xts(economics$unemploy/1000, order.by=economics$date)
eco2 <- cbind(ecoa, ecob) #가로로 두 데이터 묶어주기
#xts타입은 rename()으로 변수명을 수정할 수 없으므로 colnames() 사용
colnames(eco2) <- c("psavert","unemploy")
dygraph(eco2) %>% dyRangeSelector()
❓ 문제.
1901년부터 아메리칸리그와 내셔널리그 각각의 시즌 평균자책점을 시계열 인터랙티브 그래프로 나타내라. (Lahman 패키지 활용)
💡 정답.
ALout <- Pitching %>%
filter(yearID>=1901 & lgID=="AL")%>%
group_by(yearID) %>%
summarise(sum_out=sum(IPouts))
ALer <- Pitching %>%
filter(yearID>=1901 & lgID=="AL")%>%
group_by(yearID) %>%
summarise(sum_er=sum(ER))
NLout <- Pitching %>%
filter(yearID>=1901 & lgID=="NL")%>%
group_by(yearID) %>%
summarise(sum_out=sum(IPouts))
NLer <- Pitching %>%
filter(yearID>=1901 & lgID=="NL")%>%
group_by(yearID) %>%
summarise(sum_er=sum(ER))
ALouter <- left_join(ALout, ALer, by="yearID")
ALouter <- ALouter %>%
mutate(inn=sum_out/3) %>%
mutate(era=(9*sum_er)/inn) %>%
mutate(lgID="AL")
NLouter <- left_join(NLout, NLer, by="yearID")
NLouter <- NLouter %>%
mutate(inn=sum_out/3) %>%
mutate(era=(9*sum_er)/inn) %>%
mutate(lgID="NL")
ALLERA <- bind_rows(ALouter, NLouter)
era <- ggplot(data=ALLERA, aes(x=yearID, y=era, group=lgID, colour=lgID))+geom_line()
ggplotly(era)