1. 샤이니 app 활용 사례
1) 라이브러리, 지진 데이터 불러오기
# 지진 발생 분석 웹 어플리케이션 개발
# 0315_12_app3.R
# 데이터 준비
load("./data/earthquake/earthquake_16_21.rdata")
head(quakes)
# sn 연번, year 연도, month 월, day 일, mag 진도, depth 깊이, lat 위도, lon 경도, location 위치
library(shiny);library(leaflet);library(ggplot2);library(ggpmisc)
# install.packages(c("shiny","leaflet","ggplot2","ggpmisc"))
# ui
# bootstrapPage(): html,css,js 기능을 쉽게 사용, 웹 어플리케이션 좀 더 쉽게 개발할 수 있도록 지원. 트위터에서 개발
2) ui 만들기
ui <- bootstrapPage(
# tags$style = 부트스트랩에 적용할 영역과 대상을 선정
# 사용자 화면 페이지 스타일 설정
tags$style(type = "text/css", "html, body {width:100%;height:100%"),
# 지도 생성
leafletOutput(
outputId = "map",
width="100%",
height = "100%"),
# 메뉴 패널 (입출력 패널)
absolutePanel(top = 10,
right = 10,
# 슬라이드 입력(진도)
sliderInput(
inputId = "range", # 입력 아이디
label = "Magnitude", # 라벨
min = min(quakes$mag), # 선택 범위 최솟값
max = max(quakes$mag), # 선택 범위 최댓값
value = range(quakes$mag), # 기본 선택 범위
step = 0.5 # 단계
),
# 슬라이드 입력(기간)
sliderInput(
inputId = "time",
label = "Period",
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"
))
)
)
3) 서버 구현부터 실행까지
# 히스토그램
output$histCentile <- renderPlot({
# 데이터 없는 경우
if(nrow(filteredData()) == 0)
return(NULL)
centileBreaks <- hist(plot = F, 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 = T, 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)
)
})
}
shinyApp(ui, server)
샤이니 퍼블리싱까지 완료
4) 알록달록 꾸며보기 : 코드
# 지진 발생 분석 웹 어플리케이션 개발
# 0315_12_app3.R
# 데이터 준비
load("./data/earthquake/earthquake_16_21.rdata")
head(quakes)
# sn 연번, year 연도, month 월, day 일, mag 진도, depth 깊이, lat 위도, lon 경도, location 위치
library(shiny);library(leaflet);library(ggplot2);library(ggpmisc)
# install.packages(c("shiny","leaflet","ggplot2","ggpmisc"))
# ui
# bootstrapPage(): html,css,js 기능을 쉽게 사용, 웹 어플리케이션 좀 더 쉽게 개발할 수 있도록 지원. 트위터에서 개발
ui <- bootstrapPage(
# tags$style = 부트스트랩에 적용할 영역과 대상을 선정
# 사용자 화면 페이지 스타일 설정
tags$style(type = "text/css", "html, body {width:100%;height:100%"),
tags$h1("한국 5년간 지진 동향", style = "font-size: 20pt; font-weight: bold; text-align: center;"),
# 지도 생성
leafletOutput(
outputId = "map",
width="100%",
height = "100%"),
# 메뉴 패널 (입출력 패널)
absolutePanel(top = 120,
right = 30,
# 슬라이드 입력(진도)
sliderInput(
inputId = "range", # 입력 아이디
label = tags$span("지진 규모로 찾기", style = "color: white;"), # 라벨
min = min(quakes$mag), # 선택 범위 최솟값
max = max(quakes$mag), # 선택 범위 최댓값
value = range(quakes$mag), # 기본 선택 범위
step = 0.5 # 단계
),
# 슬라이드 입력(기간)
sliderInput(
inputId = "time",
label = tags$span("지진 연도로 찾기", style = "color: white;"),
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:white;font-weight: bold;"
))
)
)
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) %>%
addProviderTiles("NASAGIBS.ViirsEarthAtNight2012") %>%
fitBounds(~min(lon), ~min(lat), ~max(lon), ~max(lat))
})
# 지도 샘플 1
# 지도
# output$map <- renderLeaflet({
# leaflet(quakes) %>% addTiles() %>%
# setView(lng = 128, lat = 36, zoom = 6.5)
# 히스토그램
output$histCentile <- renderPlot({
# 데이터 없는 경우
if(nrow(filteredData()) == 0)
return(NULL)
# 데이터가 있는 경우
centileBreaks <- hist(plot = F, filteredData()$mag, breaks = 20)$breaks
hist(filteredData()$mag,
breaks = centileBreaks,
main = "지진 발생 정보", xlab = "진도", ylab = "빈도",
col = rainbow(10), border = 'grey')
})
# 산점도 + 회귀선
output$depth <- renderPlot({
# 데이터 없는 경우
if(nrow(filteredData()) == 0)
return(NULL)
ggplot(filteredData(), aes(x=mag, y=-depth)) +
geom_point(size=3, col="black")+
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 = T,
size = 5, col ="black",
)
})
# 입력값 변경에 따른 지도 업데이트
observe({
leafletProxy("map", data = filteredData()) %>%
clearShapes() %>% # 지도 위에 표시된 데이터 정리
addCircles(
# 로그 변환을 통해 변동성을 낮춤 (큰 숫자를 작은 숫자로 변환)
# radius = ~filteredData()$mag^6.5 # 원의 크기를 정해주는 것
radius = ~log((quakes$mag))^20,
weight = 1, # 원의 두께
color = "grey70", # 원의 둘레 색상
fillColor = "white", # 원의 내부 색상
fillOpacity = 0.6, # 투명도
popup = paste0("Time : ", filteredData()$year, "-", filteredData()$month, "-", filteredData()$day, "<br/>Place : ", filteredData()$location, "<br/>magnitude : ", filteredData()$mag)
)
})
}
shinyApp(ui, server)
* 핵심
- 변동성을 낮춰주는 함수 :
radius = ~log((quakes$mag))^20,
- 데이터 없는 경우 빈값을 표현하는 함수 :
if(nrow(filteredData()) == 0)
return(NULL)
- 입력값 변경에 따른 데이터 업데이트 해주는 함수 :
observe({})
728x90
반응형
LIST
'배운 책들 정리 > 공공데이터로 배우는 R 데이터 분석 with 샤이니' 카테고리의 다른 글
공공데이터 with 샤이니 데이터 분석 프로젝트 - 문제 정의 1 (0) | 2023.03.17 |
---|---|
공공데이터 with 샤이니 12_2 - 샤이니 app 활용 사례 (커피 전문점 접근성) (0) | 2023.03.15 |
공공데이터 with 샤이니 9,10 - 샤이니 입문하기, 데이터 분석 app 개발하기 (0) | 2023.03.14 |
공공데이터 with 샤이니 7,8 - 분석 주제를 지도로 시각화하기, 통계 분석과 시각화 (0) | 2023.03.09 |
공공데이터 with 샤이니 6,7 - 지오 데이터 프레임, 분석 주제를 지도로 시각화하기 (0) | 2023.03.08 |