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

Shiny应用CSV数据集筛选响应异常(表格无数据)求助

解决Shiny应用中数据表格无数据显示及动态更新问题

我看了你的代码,发现几个关键问题导致数据表格显示“No data available in the table”,同时折线图也可能无法正常工作,下面逐一说明并给出修复方案:

主要问题分析

  • 娱乐公司筛选逻辑错误:你用了entertainment_company == input$entertainment_companyInput,但checkboxGroupInput返回的是一个字符向量(多选时),==只能匹配单个值,应该用%in%来处理多选情况。
  • 影片类型筛选过于严格:当前代码要求genre_1、genre_2、genre_3同时属于选中的类型,这会过滤掉只有一个或两个类型匹配的影片,应该改成只要任意一个类型匹配即可。
  • 日期匹配可能不兼容:如果你的marvel_dc_movies数据集中release_date是完整日期格式(比如"2019-04-26"),而你的筛选选项是年份字符串(比如"2019"),直接用%in%会完全匹配不上,需要先从日期中提取年份。
  • 重复代码冗余:三个输出模块里都写了相同的过滤逻辑,不仅冗余还容易出错,建议用reactive()表达式统一处理过滤后的数据。
  • 折线图映射错误:geom_line()应该用color而不是fill来区分不同公司,fill是用于填充类图形(如柱状图)的参数。

修复后的完整代码

library(shiny)
library(tidyverse)
library(shinythemes)
library(lubridate) # 用于日期处理,需提前安装:install.packages("lubridate")

# 导入并预处理数据集:提取年份,处理空值
marvel_dc_movies <- read.csv("marvel_dc_movies.csv", stringsAsFactors = FALSE) %>%
  select(-X) %>% # 移除无用列
  # 从release_date提取年份(若原数据已是年份格式,可注释掉这行)
  mutate(release_year = as.character(year(ymd(release_date)))) %>%
  # 处理类型列的空值,替换为NA避免匹配错误
  mutate(across(starts_with("genre_"), ~ ifelse(. == "", NA_character_, .)))

ui <- fluidPage(
  theme = shinytheme("lumen"),
  titlePanel("Marvel Studios VS. DC Films"),
  sidebarLayout(
    sidebarPanel(
      # 上映年份多选输入框:用预处理后的年份作为选项,自动生成无需手动输入
      selectInput(
        inputId = "release_yearInput", 
        label = "Select the release year.", 
        choices = c("Unreleased", sort(unique(marvel_dc_movies$release_year))), 
        selected = "2019", 
        multiple = TRUE
      ),
      selectInput(
        inputId = "genreInput", 
        label = "Select the genre.", 
        choices = c("Action", "Adventure", "Animation", "Comedy", "Crime", "Drama", "Family", "Fantasy", "Horror", "Mystery", "Romance", "Sci-Fi", "Short", "Thriller"), 
        selected = c("Action", "Adventure", "Animation"), 
        multiple = TRUE
      ),
      sliderInput(
        inputId = "run_time_in_minInput", 
        label = "Run time in minutes.", 
        min = 0, 
        max = 200, 
        value = c(18, 181)
      ),
      checkboxGroupInput(
        inputId = "entertainment_companyInput", 
        label = "Select the entertainment company.", 
        choices = c("Marvel Studios", "DC Films"), 
        selected = c("Marvel Studios", "DC Films")
      ),
      img(src = "mvdc.jpg", height = 100, width = 230)
    ),
    mainPanel(
      tabsetPanel(
        type = "tabs",
        tabPanel("Movie list", dataTableOutput("table")),
        tabPanel("Marvel VS. DC in $", plotOutput("plot1")),
        tabPanel("Marvel VS. DC in IMDB ratings", plotOutput("plot2"))
      )
    )
  )
)

server <- function(input, output) {
  # 用reactive表达式统一处理过滤后的数据,避免重复代码
  filtered_data <- reactive({
    # 确保所有筛选参数都有输入后再执行过滤
    req(input$release_yearInput, input$genreInput, input$entertainment_companyInput)
    
    marvel_dc_movies %>% 
      filter(
        # 处理未上映影片的筛选逻辑
        (release_year %in% input$release_yearInput | release_year == "Unreleased"),
        # 任意一个类型匹配即可,同时处理NA值
        (genre_1 %in% input$genreInput | genre_2 %in% input$genreInput | genre_3 %in% input$genreInput),
        run_time_in_min >= input$run_time_in_minInput[1],
        run_time_in_min <= input$run_time_in_minInput[2],
        entertainment_company %in% input$entertainment_companyInput
      )
  })
  
  # 数据表格输出
  output$table <- renderDataTable({
    filtered_data()
  })
  
  # 票房折线图:修正color映射,添加group确保折线正确连接
  output$plot1 <- renderPlot({
    filtered_data() %>%
      ggplot(aes(x = release_year, y = gross_x1.000.000, color = entertainment_company, group = entertainment_company)) +
      geom_line(linewidth = 1) +
      labs(x = "Release Year", y = "Gross (Millions $)", color = "Production Company") +
      theme_minimal()
  })
  
  # IMDB评分折线图:同样修正映射参数
  output$plot2 <- renderPlot({
    filtered_data() %>%
      ggplot(aes(x = release_year, y = rating, color = entertainment_company, group = entertainment_company)) +
      geom_line(linewidth = 1) +
      labs(x = "Release Year", y = "IMDB Rating", color = "Production Company") +
      theme_minimal()
  })
}

shinyApp(ui = ui, server = server)

额外说明

  1. 如果你的数据集里release_date已经是纯年份格式,直接删除mutate(release_year = ...)这行即可,同时把UI里的release_yearInput改回原来的release_dateInput。
  2. 用req()函数可以避免因用户未选择筛选条件导致的报错,让应用更健壮。
  3. 类型筛选改成逻辑或(|)后,会保留所有包含选中类型的影片,符合常规筛选逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:28:00