먼저 nycflights13
데이터에서 특정 항공사 “UA”에 대한 연착 시간에 대한 데이터 프레임으로 준비한다.
library(shiny)
library(nycflights13)
library(tidyverse)
ua_data <- nycflights13::flights %>%
filter(carrier == "UA") %>%
mutate(ind_arr_delay = (arr_delay > 5)) %>%
group_by(year, month, day) %>%
summarize(
n = n(),
across(ends_with("delay"), mean, na.rm = TRUE)
%>%
) ungroup()
%>%
ua_data reactable::reactable()
viz_monthly()
함수를 준비하여 데이터프레임을 넣으면 ggplot
으로 시각화할 수 있도록 그래프를 작성한다. 월간 보고서라 1월 ~ 12월까지 해당 월을 달리하면 도착 연착, 출발 연착 등 일별로 그래프를 작성할 수 있도록 한다.
function(df, y_var, threshhold = NULL) {
viz_monthly <-
ggplot(df) +
aes(
x = .data[["day"]],
y = .data[[y_var]]
+
) geom_line() +
geom_hline(yintercept = threshhold, color = "red", linetype = 2) +
scale_x_continuous(breaks = seq(1, 29, by = 7)) +
theme_minimal()
}
%>%
ua_data filter(month == 3) %>%
viz_monthly("arr_delay", threshhold = 10)
app.R
파일을 작성하여 데이터, 함수, shiny UI, Server 모든 것을 한 파일에 작성하고 특히 reactive
를 넣어 좌측에서 해당월을 달리하면 보고서가 달리 출력되도록 웹앱을 작성한다.
해당 코드는 app.R
파일을 클릭하여 다운로드 받으면 된다.
library(shiny)
library(tidyverse)
# 데이터 ----
ua_data <- nycflights13::flights %>%
filter(carrier == "UA") %>%
mutate(ind_arr_delay = (arr_delay > 5)) %>%
group_by(year, month, day) %>%
summarize(
n = n(),
across(ends_with("delay"), mean, na.rm = TRUE)
%>%
) ungroup()
# 함수 ----
function(df, y_var, threshhold = NULL) {
viz_monthly <-
ggplot(df) +
aes(
x = .data[["day"]],
y = .data[[y_var]]
+
) geom_line() +
geom_hline(yintercept = threshhold, color = "red", linetype = 2) +
scale_x_continuous(breaks = seq(1, 29, by = 7)) +
theme_minimal()
}
# Shiny UI -------------
fluidPage(
ui <-
titlePanel("비행기 연착 보고서"),
sidebarLayout(
sidebarPanel = sidebarPanel(
selectInput("month", "월간 보고서",
choices = setNames(1:12, glue::glue("{1:12} 월")),
selected = 1
)
),
mainPanel = mainPanel(
h2(textOutput("title")),
h3("평균 도착 연착 시간"),
h4("단위: 분"),
plotOutput("flight_plot")
)
)
)
# Shiny Server -------------
function(input, output, session) {
server <-
reactive({
df_month <-%>%
ua_data filter(month == input$month)
})
reactive({
reactive_plot <-viz_monthly(df = df_month(), y_var = "arr_delay", threshhold = 10)
})
$flight_plot <- renderPlot({
output
reactive_plot()
# viz_monthly(df = df_month(), y_var = "arr_delay", threshhold = 10)
})
}
shinyApp(ui, server)
shiny
모듈을 도입하여 동일한 웹앱을 구현해보자.
shiny
모듈# 모듈 UI -------------
function(id) {
plot_ui <-
fluidRow(
column(11, plotOutput(NS(id, "flight_plot"))),
)
}
# 모듈 Server -------------
function(id, df, y_var, threshhold) {
plot_server <-
moduleServer(id, function(input, output, session) {
reactive({
reactive_plot <-viz_monthly(df = df(), y_var = y_var, threshhold = threshhold)
})
$flight_plot <- renderPlot({
outputreactive_plot()
})
}) }
shiny
웹앱library(shiny)
library(tidyverse)
source(glue::glue("{here::here()}/shiny/nycflight_module/module.R"), encoding = "UTF-8")
# 데이터 ----
ua_data <- nycflights13::flights %>%
filter(carrier == "UA") %>%
mutate(ind_arr_delay = (arr_delay > 5)) %>%
group_by(year, month, day) %>%
summarize(
n = n(),
across(ends_with("delay"), mean, na.rm = TRUE)
%>%
) ungroup()
# 함수 ----
function(df, y_var, threshhold = NULL) {
viz_monthly <-
ggplot(df) +
aes(
x = .data[["day"]],
y = .data[[y_var]]
+
) geom_line() +
geom_hline(yintercept = threshhold, color = "red", linetype = 2) +
scale_x_continuous(breaks = seq(1, 29, by = 7)) +
theme_minimal()
}
# Shiny UI -------------
fluidPage(
ui <-
titlePanel("비행기 연착 보고서"),
sidebarLayout(
sidebarPanel = sidebarPanel(
selectInput("month", "월간 보고서",
choices = setNames(1:12, glue::glue("{1:12} 월")),
selected = 1
)
),
mainPanel = mainPanel(
h2(textOutput("title")),
h3("평균 도착 연착 시간"),
h4("단위: 분"),
plot_ui("arr_delay")
)
)
)
# Shiny Server -------------
function(input, output, session) {
server <-
$title <- renderText({glue::glue("{input$month} 월 보고서")})
output
reactive({
df_month <-%>%
ua_data filter(month == input$month)
})
plot_server("arr_delay", df_month, y_var = "arr_delay", threshhold = 10)
}
shinyApp(ui, server)
shiny
모듈 개발했으면 이름 달리하여 동일한 모듈을 Shiny 앱에 넣을 수가 있다. 즉, 출발 지연 시각화를 했다면, 도착 지연 시각화도 가능하다. 모듈은 동일하여 변경할 필요는 없다.
shiny
모듈# 모듈 UI -------------
function(id) {
plot_ui <-
fluidRow(
column(11, plotOutput(NS(id, "flight_plot"))),
)
}
# 모듈 Server -------------
function(id, df, y_var, threshhold) {
plot_server <-
moduleServer(id, function(input, output, session) {
reactive({
reactive_plot <-viz_monthly(df = df(), y_var = y_var, threshhold = threshhold)
})
$flight_plot <- renderPlot({
outputreactive_plot()
})
}) }
shiny
웹앱library(shiny)
library(tidyverse)
source(glue::glue("{here::here()}/shiny/nycflight_module/module.R"), encoding = "UTF-8")
# 데이터 ----
ua_data <- nycflights13::flights %>%
filter(carrier == "UA") %>%
mutate(ind_arr_delay = (arr_delay > 5)) %>%
group_by(year, month, day) %>%
summarize(
n = n(),
across(ends_with("delay"), mean, na.rm = TRUE)
%>%
) ungroup()
# 함수 ----
function(df, y_var, threshhold = NULL) {
viz_monthly <-
ggplot(df) +
aes(
x = .data[["day"]],
y = .data[[y_var]]
+
) geom_line() +
geom_hline(yintercept = threshhold, color = "red", linetype = 2) +
scale_x_continuous(breaks = seq(1, 29, by = 7)) +
theme_minimal()
}
# Shiny UI -------------
fluidPage(
ui <-
titlePanel("비행기 연착 보고서"),
sidebarLayout(
sidebarPanel = sidebarPanel(
selectInput("month", "월간 보고서",
choices = setNames(1:12, glue::glue("{1:12} 월")),
selected = 1
)
),
mainPanel = mainPanel(
h2(textOutput("title")),
h3("평균 도착 연착 시간"),
h4("단위: 분"),
plot_ui("arr_delay"),
h3("평균 출발 연착 시간"),
h4("단위: 분"),
plot_ui("dep_delay")
)
)
)
# Shiny Server -------------
function(input, output, session) {
server <-
$title <- renderText({glue::glue("{input$month} 월 보고서")})
output
reactive({
df_month <-%>%
ua_data filter(month == input$month)
})
plot_server("arr_delay", df_month, y_var = "arr_delay", threshhold = 10)
plot_server("dep_delay", df_month, y_var = "dep_delay", threshhold = 5)
}
shinyApp(ui, server)
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com