Shiny应用中不同格式日期的标准化调整方案咨询
Shiny多日期格式兼容解决方案
核心修改思路是替换原代码中固定的ymd()日期解析逻辑,使用多格式自动识别逻辑同时适配yyyy-mm-dd和dd-mm-yyyy两种日期字符串格式,全流程统一转换为标准Date类型消除格式差异。
关键修改点
- 引入
lubridate::parse_date_time()指定两种日期解析规则,自动匹配输入格式 - 加载df后统一预处理date列为标准Date类型,避免后续重复解析出错
- 所有日期比较、范围计算逻辑全部基于标准Date类型实现,与原始字符串格式解耦
完整可运行代码
library(shiny) library(shinythemes) library(dplyr) library(ggplot2) library(tidyr) library(lubridate) function.cl<-function(dt){ # 可自由切换两种格式的df测试 df <- structure( list(date = c("2021-08-01","2021-08-01","2021-08-01","2021-08-01","2021-08-01", "2021-08-08","2021-08-08","2021-08-08","2021-08-08","2021-08-08","2021-08-08", "2021-08-13","2021-08-13","2021-08-13","2021-08-13","2021-08-13"), Week= c("Sunday","Sunday","Sunday","Sunday","Sunday","Sunday","Sunday","Sunday", "Sunday","Sunday","Sunday","Friday","Friday","Friday","Friday","Friday"), D1 = c(0,1,0,0,5,0,1,0,0,9,4,3,4,5,6,7), DR01 = c(2,1,0,0,3,0,1,0,1,7,2,3,4,6,7,8), DR02 = c(2,0,0,0,4,2,1,0,1,4,2,3,4,5,6,7), DR03 = c(2,0,0,2,6,2,0,0,1,5,2,2,4,5,7,5), DR04 = c(2,0,0,5,6,2,0,0,3,7,2,3,4,5,6,4), DR05 = c(2,0,0,5,6,2,0,0,7,7,2,3,4,5,6,7), DR06 = c(2,0,0,5,7,2,0,0,7,7,1,3,5,6,7,8), DR07 = c(2,0,0,6,9,2,0,0,7,8,1,3,5,6,4,3)), class = "data.frame", row.names = c(NA, -16L)) # df <- structure( # list(date = c("01-08-2021","01-08-2021","01-08-2021","01-08-2021","01-08-2021", # "08-08-2021","08-08-2021","08-08-2021","08-08-2021","08-08-2021","08-08-2021", # "13-08-2021","13-08-2021","13-08-2021","13-08-2021","13-08-2021"), # Week= c("Sunday","Sunday","Sunday","Sunday","Sunday","Sunday","Sunday","Sunday", # "Sunday","Sunday","Sunday","Friday","Friday","Friday","Friday","Friday"), # D1 = c(0,1,0,0,5,0,1,0,0,9,4,3,4,5,6,7), DR01 = c(2,1,0,0,3,0,1,0,1,7,2,3,4,6,7,8), # DR02 = c(2,0,0,0,4,2,1,0,1,4,2,3,4,5,6,7), DR03 = c(2,0,0,2,6,2,0,0,1,5,2,2,4,5,7,5), # DR04 = c(2,0,0,5,6,2,0,0,3,7,2,3,4,5,6,4), DR05 = c(2,0,0,5,6,2,0,0,7,7,2,3,4,5,6,7), # DR06 = c(2,0,0,5,7,2,0,0,7,7,1,3,5,6,7,8), DR07 = c(2,0,0,6,9,2,0,0,7,8,1,3,5,6,4,3)), # class = "data.frame", row.names = c(NA, -16L)) # 新增:统一预处理date列为标准Date类型,自动识别两种格式 df <- df %>% mutate(date = as.Date(parse_date_time(date, orders = c("ymd", "dmy")))) scatter_date <- function(dt, dta = df) { # 新增:dt参数也用同样规则解析,保证匹配 target_date <- as.Date(parse_date_time(dt, orders = c("ymd", "dmy"))) dta %>% filter(date == target_date) %>% summarize(across(starts_with("DR"), sum)) %>% pivot_longer(everything(), names_pattern = "DR(.+)", values_to = "val") %>% mutate(name = as.numeric(name)) %>% plot(xlab = "Days", ylab = "Types", xlim = c(0, 7)) } Plot1<-scatter_date(dt) return(list( "Plot1" = Plot1, date = unique(df$date) # 优化:直接返回去重后的标准Date类型日期列表 )) } ui <- fluidPage( ui <- shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE, br(), tabPanel("", sidebarLayout( sidebarPanel( uiOutput("date"), br(), ), mainPanel( tabsetPanel( tabPanel("",plotOutput("Graph",width = "95%", height = "600"))), )) ))) server <- function(input, output,session) { # 初始参数兼容两种格式,可替换为"01-08-2021"测试 data <- reactive(function.cl("2021-08-01")) output$date <- renderUI({ all_dates <- seq(as.Date('2021-01-01'), as.Date('2021-12-31'), by = "day") # 直接用已经转好的标准Date类型计算禁用日期,无需额外转换 disabled <- as.Date(setdiff(all_dates, data()$date), origin = "1970-01-01") dateInput(input = "date", label = "Select Date", min = min(data()$date), max = max(data()$date), value = max(data()$date), format = "dd-mm-yyyy", datesdisabled = disabled) }) output$Graph <- renderPlot({ req(input$date) function.cl(input$date)[["Plot1"]] }) } shinyApp(ui = ui, server = server)
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

