공공데이터포털 웹사이트에서 API KEY를 발급받아 “동네예보 조회서비스”에서 날씨 정보를 가져온다. 문제는 매번 시간이 지나는데 이를 계속해서 로컬 컴퓨터에서 컴파일하는 것은 사람이 할 일이 아니다. 이를 자동화하기 위해서 정확히는 돈(?)과 노력(?)을 들이지 않는 방법을 찾아보자. 이를 위해서 GitHub Actions를 염두에 두고 .Rmd
파일에 “날씨 정보를 가져와서 보고서를 HTML 파일”로 제작하는 것을 cron 작업으로 연계해보자.
먼저 기상청 날씨데이터 서비스 - 기상자료개발포털 웹사이트에서 데이터만 제공하고 있으며 관련된 RESTful API를 사용하기 위한 API KEY는 공공데이터포털 - 동네예보 조회서비스에서 받아 저장한다.
동네예보 조회서비스 오픈 API 활용가이드를 참고하면 동네를 특정하기 위한 공간지리 정보가 읍면동 단위로 상세히 제공되고 있다.
library(sf)
library(tidyverse)
library(readxl)
library(leaflet)
library(glue)
read_excel("data/기상청18_동네예보 조회서비스_오픈API활용가이드_격자_위경도(20200706).xlsx", sheet = "최종업데이트파일_20200706")
map_df <-
map_df %>%
map_df <- mutate(long = as.numeric(`경도(초/100)`),
lat = as.numeric(`위도(초/100)`))
%>%
map_df filter(`2단계` == "성남시분당구") %>%
leaflet() %>%
addProviderTiles(provider = providers$OpenStreetMap) %>%
addMarkers(lng=~long, lat = ~lat, clusterOptions = markerClusterOptions(),
popup = ~ as.character(glue("<strong> {`행정구역코드`} </strong> <br>
· 시도명: {`1단계`} <br>
· 시군구명: {`2단계`} <br>
· 읍면동: {`3단계`}")))
발급받은 API KEY를 R에서 불러와서 활용할 수 있도록 glue
팩키지와 usethis::edit_r_environ()
함수를 사용해서 API KEY정보를 저장시키고 Sys.getenv("KMA_KEY")
명령어로 불러와서 RESTful API 조회를 준비한다.
library(tidyverse)
library(glue)
Sys.getenv("KMA_KEY")
KMA_KEY <-
glue("http://apis.data.go.kr/1360000/VilageFcstInfoService/getVilageFcst?serviceKey={KMA_KEY}&numOfRows=10&pageNo=1&base_date=20201021&base_time=0230&nx=55&ny=127&dataType=JSON") kma_url <-
앞서 작성한 RESTful API 요청을 curl
명령어로 던져 결과를 확인한다.
curl --include --request GET 'http://apis.data.go.kr/1360000/VilageFcstInfoService/getVilageFcst?serviceKey=XKpB4XVSokub2d4g0ADRVllCwUM%2BwmT5k5PhBLUCXb2hcW0LgHm%2BRHs2O%2BdWi4S0JJQECMZEVEx0VV1ZuJDDUw%3D%3D&numOfRows=10&pageNo=1&base_date=20200912&base_time=0230&nx=55&ny=127&dataType=JSON'
읠挼㸸戼㸴
성남시 분당구 격자정보(X, Y)를 파악한다.
%>%
map_df filter(`2단계` == "성남시분당구") %>%
count(`격자 X`, `격자 Y`)
# A tibble: 4 x 3
`격자 X` `격자 Y` n
<chr> <chr> <int>
1 62 122 9
2 62 123 10
3 63 122 1
4 63 123 3
기상청18_동네예보 조회서비스_오픈API활용가이드.docx
문서에서 코드값 정보를 참조하여 동네예보 항목값(category)에 대한 정보를 사전에 코드화시켜 데이터프레임으로 준비한다.
tribble(~"category", ~"항목명", ~"단위",
code_table <-"POP", "강수확률", "%",
"PTY", "강수형태", "코드값",
"R06", "6시간 강수량", "범주 (1 mm)",
"REH", "습도", "%",
"S06", "6시간 신적설", "범주(1 cm)",
"SKY", "하늘상태", "코드값",
"T3H", "3시간 기온", "℃",
"TMN", "아침 최저기온", "℃",
"TMX", "낮 최고기온", "℃",
"UUU", "풍속(동서성분)", "m/s",
"VVV", "풍속(남북성분)", "m/s",
"WAV", "파고", "M",
"VEC", "풍향", "m/s",
"WSD", "풍속", "1")
격자정보 nx=62, nx=63, ny=122, ny=123 조합하면 총 4개 지역이 나오지만 먼저 nx=62, ny=122 을 조합한 성남시 분당구 한 구역만 예측 날씨값을 가져온다.
library(rvest)
library(httr)
## 날짜 전처리
Sys.Date() %>% as.character() %>%
today_date <- str_remove_all(pattern = "-")
## RESTful 호출
glue("http://apis.data.go.kr/1360000/VilageFcstInfoService/getVilageFcst?serviceKey={KMA_KEY}&numOfRows=10&pageNo=1&base_date={today_date}&base_time=0230&nx=62&ny=122&dataType=JSON")
bundang_kma_url <-
GET(bundang_kma_url)
bundang_resp <-
## JSON --> 데이터프레임 변환
jsonlite::fromJSON(content(bundang_resp, "text"), simplifyVector = FALSE)
bundang_list <-
data.frame(Reduce(rbind, bundang_list$response$body$items$item)) %>%
bundang_df <- as_tibble() %>%
mutate_all(unlist)
## 데이터프레임 가독성 있게 표현
bundang_df %>%
bundang_df <- left_join(code_table, by="category") %>%
select(fcstDate, fcstTime, category, 항목명, fcstValue, 단위)
bundang_df
# A tibble: 10 x 6
fcstDate fcstTime category 항목명 fcstValue 단위
<chr> <chr> <chr> <chr> <chr> <chr>
1 20200913 0600 POP 강수확률 20 %
2 20200913 0600 PTY 강수형태 0 코드값
3 20200913 0600 R06 6시간 강수량 0 범주 (1 mm)
4 20200913 0600 REH 습도 80 %
5 20200913 0600 S06 6시간 신적설 0 범주(1 cm)
6 20200913 0600 SKY 하늘상태 3 코드값
7 20200913 0600 T3H 3시간 기온 17 ℃
8 20200913 0600 TMN 아침 최저기온 17.0 ℃
9 20200913 0600 UUU 풍속(동서성분) 0 m/s
10 20200913 0600 VEC 풍향 360 m/s
JSON 날씨정보를 데이터프레임으로 변환시켰다면 다음 단계로 데이터 과학의 강력한 기능을 시각화를 통해 진정한 힘을 보여준다.
glue::glue("성남시 분당구 동네예보 서비스: {unique(bundang_df$fcstDate)}, {unique(bundang_df$fcstTime)}")
plot_title <-
%>%
bundang_df mutate(fcstValue = as.numeric(fcstValue)) %>%
filter(항목명 %in% c("강수확률", "습도")) %>%
ggplot(aes(x=항목명, y=fcstValue, fill = 항목명)) +
geom_col(width=0.5, show.legend = FALSE) +
facet_wrap(~항목명, scales="free_x") +
labs(x="", y="확률(%)", title=plot_title)+
theme_bw()
상기 코드가 포함된 보고서를 Rmd 스크립트로 작성한다. 문제는 API KEY가 노출된다는 점인데 이는 GitHub Action에서 다른 방식으로 보완하기로하고 우선은 제대로 동작이 되는지만 확인한다.
::embed_file('rpa-write-rmd-file.Rmd') xfun
날씨예보 보고서를 쉘환경에서 컴파일하기 때문에 먼저 rmarkdown::render()
함수로 테스트를 한다.
Rscript -e rmarkdown::render("rpa-write-rmd-file.Rmd")
::render("rpa-write-rmd-file.Rmd") rmarkdown
|
| | 0%
|
|.......... | 14%
ordinary text without R code
|
|.................... | 29%
label: unnamed-chunk-2 (with options)
List of 1
$ include: logi FALSE
|
|.............................. | 43%
ordinary text without R code
|
|........................................ | 57%
label: code-table-for-rmd
|
|.................................................. | 71%
ordinary text without R code
|
|............................................................ | 86%
label: weather-data-viz-for-rmd
|
|......................................................................| 100%
ordinary text without R code
"C:/PROGRA~3/CHOCOL~1/bin/pandoc" +RTS -K512m -RTS rpa-write-rmd-file.utf8.md --to html4 --from markdown+autolink_bare_uris+tex_math_single_backslash --output rpa-write-rmd-file.html --email-obfuscation none --self-contained --standalone --section-divs --table-of-contents --toc-depth 3 --variable toc_float=1 --variable toc_selectors=h1,h2,h3 --variable toc_collapsed=1 --variable toc_smooth_scroll=1 --variable toc_print=1 --template "C:\Users\statkclee\Documents\R\win-library\4.0\rmarkdown\rmd\h\default.html" --highlight-style tango --number-sections --variable "theme:bootstrap" --include-in-header "C:\Users\STATKC~1\AppData\Local\Temp\RtmpKcVnKY\rmarkdown-str44b4223813d7.html" --mathjax --variable "mathjax-url:https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" --lua-filter "C:/Users/statkclee/Documents/R/win-library/4.0/rmarkdown/rmd/lua/pagebreak.lua" --lua-filter "C:/Users/statkclee/Documents/R/win-library/4.0/rmarkdown/rmd/lua/latex-div.lua" --variable code_folding=hide --variable code_menu=1 --include-in-header header.html --include-after-body footer.html
1. Kaupp J. Using r to collect, analyze and visualize graduate attribute data. Proceedings of the Canadian Engineering Education Association (CEEA). 2016.
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com