如何在Shiny中用reactive函数过滤数据集?报错解决
解决Shiny应用中浓度-时间图过滤报错问题
问题背景
需创建Shiny应用,允许用户选择单个/多个研究项过滤包含浓度、时间、研究数据的数据集,展示对应的浓度-时间图。在R中常规过滤用df %>% filter(study == "1.3" & study == "2.1"),但在Shiny中编写反应式过滤逻辑时,出现报错:
Warning: Error in : You're passing a function as global data. Have you misspelled the
dataargument inggplot()
错误原因
- 反应式对象调用错误:
reactive()创建的对象是函数型反应式容器,直接将df传给ggplot()的data参数,相当于传递了函数而非实际数据集,必须加()才能获取内部数据。 - 过滤逻辑错误:多选场景下
input$study是向量,==仅能匹配第一个值,需用%in%匹配所有选中项;同时列名不能加引号,否则会变成字符串比较而非列值比较。 - 变量名冲突:反应式对象与全局数据集
df重名,导致代码混淆。
修复方案
- 重命名反应式过滤数据集,避免与全局变量冲突,例如改为
filtered_df - 修正过滤逻辑为
df %>% filter(STUDYID %in% input$study) - 在
ggplot()中调用反应式对象时添加(),即data = filtered_df() - 优化
facet_grid写法,用公式语法替代get(),避免潜在问题
修正后的完整代码
df <- MadeUpDataSet df <- df %>% filter(DV > 0.0533) # df$DV <- as.numeric(as.character(df$DV)) # df$TIME <- as.numeric(as.character(df$TIME)) # Define UI for application ui <- fluidPage( tabsetPanel(tabPanel("Tab 1", titlePanel("Shiny App: Concentration vs Time Graphs"), sidebarLayout( mainPanel("Concentration vs Time graphs", plotOutput(outputId = "plot") ), sidebarPanel(helpText("This app is developed to visualize pharmacokinetic data of different antibodies..."), selectInput( inputId = "study", label = "Include study:", choices = c("GLP Toxicity" = "ME1044-011", "Dose Range Finding", "Single Dose", "Repeat Dose"), selected = "ME1044-011", multiple = T ), selectInput( inputId = "x", label = "X-axis:", choices = c("Time" = "TIME", "TLD"), selected = "Time" ), selectInput( inputId = 'column', label = "Columns for:", choices = c("Dose mg/kg" = "DOSEMGKG", "Species" = "SPECIES", "Antibody" = "ABXID", "Subspecies" = "SUBSPECIES", "Age" = "AGE", "Animal ID" = "ANIMALID"), selected = "DOSEMGKG" ), selectInput( inputId = 'row', label = "Rows for:", choices = c("Dose mg/kg" = "DOSEMGKG", "Species" = "SPECIES", "Antibody" = "ABXID", "Subspecies" = "SUBSPECIES", "Age" = "AGE", "Animal ID" = "ANIMALID"), selected = "ABXID" ), selectInput( inputId = "group", label = "Group by:", choices = c("Dose mg/kg" = "DOSEMGKG", "Species" = "SPECIES", "Antibody" = "ABXID", "Subspecies" = "SUBSPECIES", "Age" = "AGE", "Animal ID" = "ANIMALID"), selected = "ANIMALID" ), sliderInput( inputId = 'trange', label = "Time range:", min = 0, max = 1704, value = c(0, 1704 ) ) )) )), tabsetPanel(tabPanel("Tab 2", titlePanel("Tab 2"), sidebarLayout( mainPanel("Plot #2", plotOutput(outputId = "plot2") ), sidebarPanel(helpText("Whatever text..."), selectInput( inputId = 't', label = "Example", choices = c("#1", "#2", "#3"), selected = "#1" ) ) ))) ) # Define server server <- function(input, output, session){ # 修正:重命名反应式对象,修正过滤逻辑 filtered_df <- reactive({ df %>% filter(STUDYID %in% input$study) }) output$plot <- renderPlot({ # 修正:调用反应式对象加(),优化facet_grid写法 ggplot(data = filtered_df(), aes_string(x = input$x, y = "DV", col = input$group)) + xlab("Time") + ylab("Concentration (ug/mL)") + geom_point() + facet_grid(as.formula(paste(input$row, "~", input$column))) + scale_x_continuous(limits = input$trange) + theme_bw() }) } shinyApp(ui = ui, server = server)
内容的提问来源于stack exchange,提问作者AsGi
相关产品推荐
相关产品推荐

