Shiny App中基于所选日期计算上周训练时长差值报错排查
问题根源与解决办法
嘿,这个报错的核心原因其实很明确——input$dateInput的类型是字符串,而不是你以为的日期(Date)类型!
你看,max(Data$WeekEnding)是原生的Date类型,R对Date类型支持直接加减天数的操作,所以max(Data$WeekEnding)-7能正常运行;但selectInput组件默认会把用户选择的日期转换成字符串返回给input$dateInput,你试图给一个字符串减7,R肯定会报错说“非数值参数不能做二元运算”呀。
两种快速修复方案
方案1:在Server里转换输入类型
在计算差值之前,把input$dateInput转换成Date类型就行,修改后的output$results代码如下:
output$results <- renderFormattable({ # 先把输入的字符串转成Date类型 selected_date <- as.Date(input$dateInput) # 直接计算上周日期 prev_week <- selected_date - 7 Table <- data.table( "Variable" = c("Total Training (hrs)"), "Last Week" = c(sum(Data$TotalTraining.hrs[Data$WeekEnding == selected_date])), "Change" = c( sum(Data$TotalTraining.hrs[Data$WeekEnding == selected_date]) - sum(Data$TotalTraining.hrs[Data$WeekEnding == prev_week]) ) ) formattable(Table, align= c("l", "c", "c"), list(Change = formatter("span", style = x ~ style(font.weight = "bold", color = ifelse(x > 0, "green", ifelse(x < 0, "red", "black"))), x ~ icontext(ifelse(x>0, "arrow-up", ifelse(x<0, "arrow-down", "")), x)))) })
方案2:换用更适合的日期输入组件
如果不想每次都手动转换类型,推荐直接用dateInput替代selectInput,它默认返回Date类型,完全避免类型问题:
sidebarPanel( dateInput("dateInput", "Week Ending", value = max(Data$WeekEnding), # 默认选中最新周 min = min(Data$WeekEnding), # 限制最小可选日期 max = max(Data$WeekEnding)) # 限制最大可选日期 )
用这个组件的话,你原来的Server代码里input$dateInput -7就能直接正常运行,不需要额外转换。
额外小优化
如果你坚持要用selectInput,可以给选项统一转成字符串,避免潜在的类型混乱:
sidebarPanel( selectInput("dateInput", "Week Ending", choices = as.character(Data$WeekEnding), selected = as.character(max(Data$WeekEnding))) )
当然,这样还是需要在Server里用as.Date()转换后再做减法。
修改后再运行,就能正常根据选择的日期计算当周训练时长和上周的差值啦~
内容的提问来源于stack exchange,提问作者wattss
相关产品推荐
相关产品推荐

