如何解决R(Shiny)中第二种代码方案的日历控件报错问题
问题根因
- 核心错误:第二种方案的
function.cl函数返回值调整后丢失了原始数据框。第一种方案该函数直接返回生成的df数据框,可通过data()$date正常读取日期列;第二种方案仅返回包含Plot1的列表,没有返回df,导致data()$date为空值,调用min、max计算日期范围时触发报错。 - 绘图逻辑错误:base R的
plot()函数直接调用时不会返回可复用的绘图对象,在function.cl中提前绘图、再将返回值传入renderPlot的写法无法正常渲染图形。 - 隐藏逻辑隐患:df中的date、Update列均为字符串格式,直接用
<比较会按字符串规则判断,存在日期比较错误的问题。
修复方案
调整function.cl的返回值,保留原始数据框,将绘图逻辑移到renderPlot中,同时将日期列统一转为Date类型,修复后完整代码如下:
library(shiny) library(shinythemes) function.cl<-function(){ df <- structure( list(Update = c("2021-08-21","2021-08-21","2021-08-21","2021-08-21","2021-08-21"), date = c("2021-04-01","2021-05-02","2021-06-03","2021-07-04","2021-08-05"), D1 = c(3,1,4,5,6), DR01 = c(2,4,5,6,7), DR02 = c(6,3,2,6,1),DR03 = c(5,2,8,9,7), DR04 = c(3,5,3,3,7)),class = "data.frame", row.names = c(NA, -5L)) # 统一转为日期类型避免比较错误 df$Update <- as.Date(df$Update) df$date <- as.Date(df$date) historic<-subset(df,df$date<df$Update) average<-mean(historic$D1) standard<-sd(historic$D1) evol<-subset(df,df$date<df$Update) median_ocup<-sapply(evol[startsWith(names(evol), "DR")], median) # 返回所有需要用到的数据,不提前执行绘图 return(list( "df" = df, "average" = average, "standard" = standard, "median_ocup" = median_ocup )) } ui <- fluidPage( shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE, br(), tabPanel("", sidebarLayout( sidebarPanel( uiOutput("date"), plotOutput("Graph"), br(), ), mainPanel( )) ))) server <- function(input, output,session) { data <- reactive(function.cl()) output$date <- renderUI({ # 从返回结果中取数据框再读取日期列 df <- data()$df # 调整可选日期范围覆盖df中的实际日期 all_dates <- seq(as.Date('2021-01-01'), as.Date('2021-12-31'), by = "day") disabled <- as.Date(setdiff(all_dates, df$date), origin = "1970-01-01") dateInput(input = "date", label = "Select Date", min = min(df$date), max = max(df$date), value = max(df$date), format = "dd-mm-yyyy", datesdisabled = disabled) }) output$Graph <- renderPlot({ # 绘图逻辑移到renderPlot中执行 res <- data() plot(res$median_ocup[1:10],xlab="Days",ylab="Number",ylim=c(1, 6)) abline(h=c(res$average-res$standard, res$average, res$average+res$standard), col="red", lwd=5) }) } shinyApp(ui = ui, server = server)
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

