Я хочу создать Shinydashboard, который требует, чтобы пользователь загрузил файл csv и ввел «емкость». Панель управления должна производить расчет и отображать доход, транзакцию и процент занятости на странице «Обзор», которая отображает 3 информационных окна.
В настоящий момент страница «Обзор» пуста перед загрузкой файла csv и вводит числовые значения c в "вместимость". Как только оба требования будут выполнены, все информационное окно появится и отобразит расчет.
Однако я бы хотел, чтобы на странице «Обзор» отображалось все информационное окно даже без загруженного файла csv и предоставленной емкости (конечно, информационное окно будет показывать НУЛЬ ). После загрузки файла csv и предоставления емкости значения инфобокса изменятся соответственно.
Чего не хватает в моих кодах? Оцените ваш совет.
library(shinydashboard)
library(tidyverse)
library(lubridate)
ui <- dashboardPage(
dashboardHeader(title = "B. Times Square"),
dashboardSidebar(
sidebarMenu(
menuItem(text = "Overview", tabName = "overview", icon = icon("balance-scale-right")),
menuItem(text = "File Upload", tabName = "data", icon = icon("file-upload"))
)
),
dashboardBody(
tabItems(
tabItem(tabName = "overview",
fluidRow(
infoBoxOutput(outputId = "i.revenue"),
infoBoxOutput(outputId = "i.transaction"),
infoBoxOutput(outputId = "i.rate")
)
),
tabItem(tabName = "data",
column(width = 4,
fluidRow(
inputPanel(
fileInput(inputId = "csv", label = "File upload:", accept = ".csv"),
numericInput(inputId = "capacity", label = "Capacity", value = 0)
)
)
)
server <- function(input, output) {
df.transaction <- reactive({
req(input$csv$datapath)
data_type <- list(
id = col_character(),
status = col_character(),
book_channel = col_character(),
book_datetime = col_datetime(),
check_in = col_date(),
check_out = col_date(),
total_amount = col_double()
)
data_1 <- read_csv(input$csv$datapath, col_types = data_type) %>%
filter(!(is.na(check_in) | is.na(total_amount)) & total_amount != 0) %>%
# recode book_channel with acronym
# recode status so that only "Book"/"Cancel" status remains
mutate(book_channel = case_when(book_channel == "Flight Centre Travel Group" ~ "FCTG",
book_channel == "HRS - Hotel Reservation Service" ~ "HRS",
book_channel == "My Bookings/Entertainment Book" ~ "MBEB",
book_channel == "WebBeds - Sunhotels" ~ "WebBeds-S",
book_channel == "WebBeds - Destinations of the World" ~ "WebBeds-DOTW",
book_channel == "Asian Overland Services" ~ "AOS",
book_channel == "Egypt Express Travel" ~ "EET",
book_channel == "MG Holiday (OLD)" ~ "MGH",
TRUE ~ book_channel),
book_channel = as_factor(book_channel),
book_date = str_split(book_datetime, " ", simplify = TRUE)[,1],
book_time = str_split(book_datetime, " ", simplify = TRUE)[,2],
lead_time = time_length(interval(book_date, check_in), "day"),
lead_time = if_else(lead_time < 0, 0, lead_time),
overnight = time_length(interval(check_in, check_out), "day"),
status = if_else(status %in% c("Booked", "Modified"), "Book", "Cancel"),
status = as_factor(status)
) %>%
select(id, status, book_channel, book_date, book_time, check_in, check_out, lead_time, overnight, total_amount)
})
df.occupancy <- reactive({
req(input$csv$datapath)
data_type_2 <- list(
id = col_character(),
status = col_character(),
book_channel = col_character(),
book_datetime = col_datetime(),
check_in = col_date(),
check_out = col_date(),
total_amount = col_double()
)
data_2 <- read_csv(input$csv$datapath, col_types = data_type_2) %>%
filter(!(is.na(check_in) | is.na(total_amount)) & total_amount != 0) %>%
# recode book_channel with acronym
# recode status so that only "Book"/"Cancel" status remains
mutate(book_channel = case_when(book_channel == "Flight Centre Travel Group" ~ "FCTG",
book_channel == "HRS - Hotel Reservation Service" ~ "HRS",
book_channel == "My Bookings/Entertainment Book" ~ "MBEB",
book_channel == "WebBeds - Sunhotels" ~ "WebBeds-S",
book_channel == "WebBeds - Destinations of the World" ~ "WebBeds-DOTW",
book_channel == "Asian Overland Services" ~ "AOS",
book_channel == "Egypt Express Travel" ~ "EET",
book_channel == "MG Holiday (OLD)" ~ "MGH",
TRUE ~ book_channel),
book_channel = as_factor(book_channel),
status = if_else(status %in% c("Booked", "Modified"), "Book", "Cancel"),
status = as_factor(status)
) %>%
filter(status == "Book") %>%
mutate(check_in = map2(check_in, check_out, ~ seq(.x, .y - 1, "day"))) %>%
unnest(check_in) %>% group_by(id) %>% add_count() %>%
mutate(check_out = check_out - rev(row_number() - 1),
total_amount = total_amount / n) %>%
select(- c(status, n))
})
output$i.revenue <- renderInfoBox({
revenue.dollar <- df.transaction()$total_amount %>% sum() %>% round()
infoBox(title = "Revenue", icon = icon("hand-holding-usd"), value = revenue.dollar)
})
output$i.transaction <- renderInfoBox({
transaction.count <- df.transaction() %>% nrow()
infoBox(title = "Transaction", icon = icon("bed"), value = transaction.count)
})
output$i.rate <- renderInfoBox({
occupancy <- df.occupancy() %>% nrow()
occupancy <- round(occupancy * 100 / (input$capacity * 365))
infoBox(title = "Occupancy %", icon = icon("percentage"), value = occupancy)
})
}
shinyApp(ui = ui, server = server)