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)
额外说明
- 如果你的数据集里
release_date已经是纯年份格式,直接删除mutate(release_year = ...)这行即可,同时把UI里的release_yearInput改回原来的release_dateInput。 - 用
req()函数可以避免因用户未选择筛选条件导致的报错,让应用更健壮。 - 类型筛选改成逻辑或(
|)后,会保留所有包含选中类型的影片,符合常规筛选逻辑。
内容的提问来源于stack exchange,提问作者sbcmx
相关产品推荐
相关产品推荐

