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

如何在R Shiny中实现各训练项目覆盖距离的求和功能?

实现Shiny训练计划总覆盖米数求和的方案

要实现所有选中训练项目的覆盖米数求和,你可以通过以下两步修改现有代码:

1. 在UI中添加总米数显示区域

在mainPanel的末尾添加专门的区块,用于展示所有训练项目的总覆盖米数:

br(),
h3("Total Meters Covered"),
textOutput("totalMeters")

2. 在Server中实现总和计算逻辑

创建反应式计算逻辑,动态遍历用户选中的所有训练项目,分别计算单个项目的覆盖米数后求和:

核心逻辑说明

  • 获取用户设置的训练项目数量input$num
  • 遍历1到input$num的每个项目,获取对应的训练类型选择和时长滑块值
  • 从MyData中匹配对应训练的每分钟覆盖米数,计算单个项目的总米数
  • 对所有有效项目的米数求和,同时处理未选择训练或时长为0的情况,避免NA干扰计算

修改后的完整代码

library(shiny)
library(dplyr)

MyData <- structure(list(Drill = c("GP Warm Up", "5v2 Rondo", "11v11",  "10v6 Drop Behind Ball"), 
                         PlayerLoadPerMinute = c(7.72949670665213,  6.49382926701571,
                                                 9.67483408668731, 5.86770863636364), 
                         MetersPerMinute = c(69.9524820610687,
                                            45.823744973822, 95.9405092879257, 58.185375), 
                         class = "data.frame", row.names = c(NA,  -4L)))

# Define UI ----
ui <- fluidPage(
  titlePanel("Practice Planner"),
  sidebarLayout(
    sidebarPanel(
      numericInput("num", h3("Number of Drills"), value = 1, min = 1, max = 10)
    ),
    mainPanel(
      # 第一个训练项目
      selectInput("DrillName1",
                  label = "Choose a Drill:",
                  choices = unique(MyData$Drill),
                  selected = NULL,
                  multiple = FALSE),
      sliderInput("slider1", 
                  label = h3("Duration (minutes)"), 
                  min = 0, 
                  max = 60, 
                  value = 0),
      textOutput("MpM1"),
      br(),
      # 第二个训练项目(条件显示)
      conditionalPanel(
        condition = "input.num > 1",
        selectInput("DrillName2",
                    label = "Choose a Drill:",
                    choices = unique(MyData$Drill),
                    selected = NULL,
                    multiple = FALSE),
        sliderInput("slider2", 
                    label = h3("Duration (minutes)"), 
                    min = 0, 
                    max = 60, 
                    value = 0),
        textOutput("MpM2")),
      br(),
      # 第三个训练项目(条件显示)
      conditionalPanel(
        condition = "input.num > 2",
        selectInput("DrillName3",
                    label = "Choose a Drill:",
                    choices = unique(MyData$Drill),
                    selected = NULL,
                    multiple = FALSE),
        sliderInput("slider3", 
                    label = h3("Duration (minutes)"), 
                    min = 0, 
                    max = 60, 
                    value = 0),
        textOutput("MpM3")),
      # 总米数显示区域
      br(),
      h3("Total Meters Covered"),
      textOutput("totalMeters")
    )
  )
)

# Define server logic  ----
server <- function(input, output, session) {
  # 计算单个训练项目的覆盖米数
  lapply(1:10, function(x) {
    output[[paste0("MpM", x)]] <- renderText({
      chosendrill <- input[[paste0("DrillName", x)]]
      duration <- input[[paste0("slider", x)]]
      if(is.null(chosendrill) || duration == 0) {
        return("Meters covered: 0")
      }
      meters <- MyData$MetersPerMinute[MyData$Drill == chosendrill] * duration
      paste0("Meters covered: ", round(meters, 2))
    })
  })
  
  # 计算总覆盖米数
  output$totalMeters <- renderText({
    num_drills <- input$num
    total <- 0
    for(i in 1:num_drills) {
      drill_name <- input[[paste0("DrillName", i)]]
      duration <- input[[paste0("slider", i)]]
      if(!is.null(drill_name) && duration > 0) {
        meters_per_min <- MyData$MetersPerMinute[MyData$Drill == drill_name]
        total <- total + (meters_per_min * duration)
      }
    }
    paste0("Total: ", round(total, 2))
  })
}

# Create Shiny app ----
shinyApp(ui = ui, server = server)

额外优化说明

  • 给numericInput添加了min=1, max=10的限制,避免超出预设的训练项目数量范围
  • 修改滑块标签为"Duration (minutes)",语义更清晰
  • 单个项目计算中增加空值/零时长处理,避免显示无效的NA结果
  • 所有米数结果保留两位小数,显示更美观规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:19