You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用开发需求:生成时序化Cases数据集并绘制折线图

Shiny应用折线图实现方案

针对你的需求,我们需要调整数据处理逻辑,确保折线图X轴按时间顺序排列,同时正确计算每个月份的案例数量。以下是完整的修改后代码:

library(shiny)
library(bupaR)
library(ggplot2)
library(dplyr)
library(zoo)

# 原始数据保持不变
mydata <- structure(list(case_id = c("WC4120721", "WC4120667", "WC4120689", 
                                   "WC4121068", "WC4120667", "WC4121937", "WC4121767", "WC4121952", 
                                   "WC4121889", "WC4121921", "WC4121870"), lifecycle = c(110, 110, 
                                                                                         110, 110, 120, 110, 110, 110, 110, 10, 110), action = c("WC4120721-CN354877", 
                                                                                                                                                 "WC4120667-CN354878", "WC4120689-CN356752", "WC4121068-CN301950", 
                                                                                                                                                 "WC4120667-CSW310", "WC4121937-CN301302", "WC4121767-CN354089", 
                                                                                                                                                 "WC4121952-CN355950", "WC4121889-CN301291", "WC4121921-CSW304", 
                                                                                                                                                 "WC4121870-CN301116"), activity = c("Forged Wire, Medium (Sport)", 
                                                                                                                                                                                     "Forged Wire, Medium (Sport)", "Forged Wire, Medium (Sport)", 
                                                                                                                                                                                     "Forged Wire, Medium (Sport)", "BBH-1&2", "Needle Point", "Brazing Machines", 
                                                                                                                                                                                     "Needle Point", "Needle Point", "SOLO Salt", "Needle Point"), 
                       resource = c("3419", "3216", "3409", "3201", "C3-100", "6206", 
                                    "7709", "6201", "5202", "C3-040", "5503"), timestamp = structure(c(1606975200, 
                                                                                                       1607126280, 1607446560, 1607578920, 1607641020, 1609695420, 
                                                                                                       1609696800, 1609697040, 1609697460, 1609697460, 1609700340
                                    ), tzone = "UTC", class = c("POSIXct", "POSIXt")), Date = c("December-20", 
                                                                                                "December-20", "December-20", "December-20", "December-20", 
                                                                                                "January-21", "January-21", "January-21", "January-21", "January-21", 
                                                                                                "January-21"), .order = c(1L, 2L, 3L, 4L, 5L, 86L, 87L, 88L, 
                                                                                                                          89L, 90L, 91L)), row.names = c(NA, -11L), class = c("eventlog", 
                                                                                                                                                                              "log", "tbl_df", "tbl", "data.frame"), case_id = "case_id", activity_id = "activity", activity_instance_id = "action", lifecycle_id = "lifecycle", resource_id = "resource", timestamp = "timestamp")

# 预处理Date字段,转换为可排序的yearmon类型,并生成格式化后的显示文本
mydata <- mydata %>%
  mutate(
    yearmon = zoo::as.yearmon(Date, "%B-%y"),
    Month_Formatted = format(yearmon, "%B-%y") # 保持原格式显示,或者改成"%Y-%m"
    # Month_Formatted = format(yearmon, "%Y-%m") # 如果需要显示为2020-12这种格式,用这行替换上一行
  )

ui <- fluidPage(
  # 选择框选项按时间顺序排列
  selectInput("mon", "选择月份", 
              choices = unique(mydata$Month_Formatted)[order(unique(mydata$yearmon))],
              selected = unique(mydata$Month_Formatted)[order(unique(mydata$yearmon))],
              multiple = TRUE),  
  verbatimTextOutput("cases"),
  plotOutput("linechart")
)

server <- function(input, output, session) {
  # 筛选选中月份的数据
  mydata2 <- reactive({
    req(input$mon)
    mydata %>%
      filter(Month_Formatted %in% input$mon)
  }) 
  
  # 计算选中月份的总案例数
  output$cases <- renderPrint({
    bupaR::n_cases(mydata2())
  })
  
  # 生成折线图数据:按月份聚合案例数
  plot_data <- reactive({
    req(mydata2())
    mydata2() %>%
      distinct(case_id, yearmon, Month_Formatted) %>% # 每个案例只算一次
      group_by(yearmon, Month_Formatted) %>%
      summarise(Cases = n(), .groups = "drop") %>%
      arrange(yearmon) # 确保按时间顺序排列
  })
  
  # 绘制折线图
  output$linechart <- renderPlot({
    req(plot_data())
    ggplot(data = plot_data(), aes(x = yearmon, y = Cases)) +
      geom_line(color = "#2c3e50", linewidth = 1) +
      geom_point(size = 3, color = "#e74c3c") +
      scale_x_yearmon(format = "%B-%y") + # 对应显示格式,改成"%Y-%m"如果需要
      labs(x = "月份", y = "案例数量", title = "每月案例数量趋势") +
      theme_minimal()
  })
}

shinyApp(ui = ui, server = server)

核心修改说明

  • 时间格式转换:用zoo::as.yearmon将原有的"December-20"字符串转换为可排序的时间类型,彻底解决X轴顺序混乱问题
  • 数据聚合:通过distinct(case_id, ...)确保每个案例只被统计一次,再按月份分组计算案例数,生成包含Month_Formatted和Cases的目标结构
  • 选择框排序:初始化选择框时按时间顺序排列选项,用户选择后折线图始终保持正确的时间顺序
  • 灵活的显示格式:如果需要将月份显示为2020-12这种格式,只需修改两处format函数的参数为"%Y-%m"即可

内容的提问来源于stack exchange,提问作者firmo23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:05:36