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

R Shiny技术问题:基于多选框分组数据并绘制多折线图

R Shiny:按测试类型分组统计与折线图实现

核心问题拆解

你需要实现:针对选中的id,在指定日期区间内,按多选框选择的测试类型(A/B/C)分别统计每日记录数,并绘制多折线图。原数据为宽格式(每个测试类型对应多列),核心是先将数据转换为长格式,再按测试类型分组统计。

解决方案步骤

1. 数据格式转换(宽转长)

原数据中,batch_a_1/batch_a_2对应测试A,batch_b_1/batch_b_2对应测试B,batch_c_2对应测试C。需用tidyr::pivot_longer将这些列转为长格式,提取测试类型,筛选出值为1的有效记录(代表该测试有记录)。

2. 结合Shiny输入过滤并统计

根据用户选择的id、日期区间、测试类型,过滤数据后,按date和test_type分组,统计每日各测试的记录总数。

3. 绘制多折线图

用ggplot2绘制折线图,不同测试类型用不同颜色区分。

完整Shiny示例代码

library(shiny)
library(tidyverse)

# 模拟数据集
mydata <- tibble(
  id = c("rec1", "rec2", "rec3", "rec1", "rec1", "rec2", "rec3", "rec3"),
  date = as.Date(c("2022-01-01", "2022-01-03", "2022-01-01", "2022-01-03", 
                   "2022-01-01", "2022-01-03", "2022-01-01", "2022-01-03")),
  batch_a_1 = c(1,0,1,0,1,0,1,0),
  batch_a_2 = c(0,1,0,1,0,1,0,1),
  batch_b_1 = c(1,0,1,0,1,0,1,0),
  batch_b_2 = c(0,0,0,1,0,0,0,1),
  batch_c_2 = c(1,0,0,0,0,1,0,0)
)

ui <- fluidPage(
  selectInput("id", "选择ID", choices = unique(mydata$id)),
  dateRangeInput("Dates", "选择日期区间", start = min(mydata$date), end = max(mydata$date)),
  checkboxGroupInput(
    inputId = "test",
    choices = c("A", "B", "C"),
    selected = c("A", "B", "C"),
    label = "选择测试类型"
  ),
  plotOutput("test_trend")
)

server <- function(input, output) {
  # 处理数据:转换格式+过滤+统计
  processed_data <- reactive({
    mydata %>%
      # 宽转长:提取测试类型,筛选值为1的记录
      pivot_longer(cols = starts_with("batch_"), 
                   names_to = "test_type", 
                   values_to = "has_record") %>%
      mutate(test_type = str_extract(test_type, "[a-z]") %>% toupper()) %>% # 提取A/B/C
      filter(has_record == 1) %>%
      # 应用Shiny输入过滤
      filter(
        id == input$id,
        test_type %in% input$test,
        date >= input$Dates[1],
        date <= input$Dates[2]
      ) %>%
      # 按日期和测试类型统计总数
      count(date, test_type, name = "record_count")
  })
  
  # 绘制折线图
  output$test_trend <- renderPlot({
    processed_data() %>%
      ggplot(aes(x = date, y = record_count, color = test_type, group = test_type)) +
      geom_line(size = 1) +
      geom_point() +
      labs(x = "日期", y = "记录总数", color = "测试类型") +
      theme_minimal()
  })
}

shinyApp(ui, server)

关键代码解释

  • 宽转长:pivot_longer将所有batch_开头的列转为长格式,str_extract从列名中提取测试类型(A/B/C),并筛选出has_record == 1的有效记录。
  • 过滤逻辑:直接按test_type %in% input$test筛选选中的测试类型,同时匹配id和日期区间。
  • 分组统计:count(date, test_type)自动按日期和测试类型分组,统计每组的记录数。
  • 折线图绘制:用color = test_type区分不同测试类型的折线,group = test_type确保每个测试类型单独成线。

注意事项

  • 如果原数据中测试列的命名规则不同(比如不是batch_x_*),需要调整str_extract的正则表达式,确保正确提取测试类型。
  • 若日期区间内某测试类型无记录,折线图会自动忽略该类型,可通过complete(date, test_type, fill = list(record_count = 0))补全0值,让折线显示为0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:05:31