본문 바로가기
데이터분석/R

[R 데이터분석 with 샤이니] 지진 발생 분석 (Shiny)

by 버섯도리 2022. 7. 26.

earthquake_16_21.rdata
0.01MB

> ## 12-3 지진 발생 분석하기

> # Step 1 : 데이터 준비하기

> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> load("./01_code/earthquake/earthquake_16_21.rdata")
> head(quakes)
   sn year month day mag depth   lat    lon                              location
1 816 2021    12  30 2.2    14 41.30 129.17 북한 함경북도 길주 북북서쪽 41km 지역
2 815 2021    12  30 2.3    19 41.31 129.21 북한 함경북도 길주 북북서쪽 41km 지역
3 814 2021    12  17 3.2    18 33.12 126.18      제주 서귀포시 서남서쪽 38km 해역
4 813 2021    12  15 2.3    10 35.79 127.80          경남 거창군 북서쪽 15km 지역
5 812 2021    12  15 2.8    14 33.14 126.15      제주 서귀포시 서남서쪽 40km 해역
6 811 2021    12  14 4.9    17 33.09 126.16      제주 서귀포시 서남서쪽 41km 해역

> # Step 2 : 사용자 화면 구현하기

> library(shiny)
> library(leaflet)
> library(ggplot2)
> library(ggpmisc)

> ui <- bootstrapPage(
+   #---# 사용자 화면 페이지 스타일 설정
+   tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
+   #---# 지도 생성
+   leafletOutput("map", width = "100%", height = "100%"),
+   #---# 메뉴 패널
+   absolutePanel(top = 10, right = 30,
+                 sliderInput(
+                   inputId = "range",
+                   label = "진도",
+                   min = min(quakes$mag),
+                   max = max(quakes$mag),
+                   value = range(quakes$mag),
+                   step = 0.5
+                 ),
+                 sliderInput(
+                   inputId = "time",
+                   label = "기간",
+                   sep = "",
+                   min = min(quakes$year),
+                   max = max(quakes$year),
+                   value = range(quakes$year),
+                   step = 1
+                 ),
+                 plotOutput("histCentile", height = 230),
+                 plotOutput("depth", height = 230),
+                 p(span("자료 출처 : 기상청", align = "center", style = "color:black;background-color:white"))
+   )
+ )

> # Step 3 : 서버 구현하기

> server <- function(input, output, session) {
+   #---# 반응식
+   filteredData <- reactive({
+     quakes[quakes$mag >= input$range[1] & quakes$mag <= input$range[2] &
+              quakes$year >= input$time[1] & quakes$year <= input$time[2], ]
+   })
+   #---# 지도
+   output$map <- renderLeaflet({
+     leaflet(quakes) %>% addTiles() %>%
+       # 지도 경계 지점의 위치 설정
+       fitBounds(~min(lon), ~min(lat), ~max(lon), ~max(lat))
+   })
+   #---# 히스토그램
+   output$histCentile <- renderPlot({
+     if (nrow(filteredData()) == 0)
+       return(NULL)
+     centileBreaks <- hist(plot = FALSE, filteredData()$mag, breaks = 20)$breaks
+     hist(filteredData()$mag, breaks = centileBreaks,
+          main = "지진 발생 정보", xlab = "진도", ylab = "빈도",
+          col = "blue", border = "grey")
+   })
+   #---# 회귀 분석
+   output$depth <- renderPlot({
+     ggplot(filteredData(), aes(x = mag, y = -depth)) +
+       geom_point(size = 3, col = "red") +
+       geom_smooth(method = "lm", col = "blue") +
+       xlab("진도") + ylab("깊이") +
+       stat_poly_eq(aes(label = paste(..eq.label..)),
+                    label.x = "right", label.y = "top",
+                    formula = y ~ x, parse = TRUE, size = 5, col = "black")
+   })
+   #---# 입력값 변경에 따른 지도 업데이트
+   observe({
+     leafletProxy("map", data = filteredData()) %>% clearShapes() %>%
+       addCircles(
+         radius = ~log((quakes$mag))^20, # 원 크기 설정
+         weight = 1, color = "grey70",
+         fillColor = "red", fillOpacity = 0.6, popup = ~paste(mag)
+       )
+   })
+ }

> # Step 4 : 애플리케이션 실행하기

> shinyApp(ui = ui, server = server)

Listening on http://127.0.0.1:5417

 

 

 

 

 

 

 

출처 : 김철민, ⌜공공데이터로 배우는 R 데이터분석 with 샤이니⌟, 이지스퍼블리싱, 2022