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

Shiny下拉框筛选含2个冒号的交互项时失效问题排查

Shiny下拉框显示异常问题排查与解决

问题描述

在大型Shiny应用中,基于ANOVA输出创建绘图用下拉框,通过行名中的冒号数量区分交互项:1个冒号对应双向交互,2个冒号对应三向交互。当筛选双向交互或所有交互项时,下拉框工作正常;但筛选三向交互(将模式匹配条件改为>1或==2)时,下拉框显示choices对应的dataframe名称而非选项本身,虽能返回选中值但显示异常。

错误原因

selectInput的choices参数接受向量或命名列表:

  • 当传入的dataframe包含多行数据时,Shiny会自动提取列值作为选项,显示正常;
  • 当dataframe仅包含一行数据时,Shiny会将其解析为以列名为键、行值为值的命名列表,导致下拉框显示列名而非实际交互项。

解决方法

直接传入字符向量而非dataframe给choices参数,有两种实现方式:

方式1:直接生成筛选后的字符向量(推荐)

去掉不必要的dataframe转换,直接筛选行名生成向量:

# 替换原代码中int_sel相关的行
int_sel <- rownames(head(aov_l,-1)) %>%
  keep(~str_count(.x, pattern = ":") > 1) # 筛选三向交互(冒号数>1)

方式2:从dataframe中提取列向量

如果保留dataframe处理流程,需提取对应列的向量传入choices:

# 原int_sel处理不变,修改selectInput的choices参数
selectInput(inputId = "ems_int_selected",
            label = int_title,
            choices = int_sel$Interactions, # 提取列向量
            multiple = TRUE,
            width = "100%"
)

修正后的完整代码

library(shiny)
library(dplyr)
library(stringr) # 需加载stringr包,原代码用到str_count但未显式加载

# Define UI
ui <- fluidPage(
    uiOutput("ems_int_sel"),
    textOutput("selection")
)

# Define server logic
server <- function(input, output) {
    output$ems_int_sel<-renderUI({
      aov_l<-structure(list(Df = c(1, 1, 1, 1, 1, 1, 1, 72), 
                            SS = c(0.199999999999973,0.112500000000021, 2.4500000000001, 25.3124999999997, 4.99999999999986,0.11249999999998, 1.07995057924757e-27, 13.9999999999996), 
                            MS = c(0.199999999999973,0.112500000000021, 2.4500000000001, 25.3124999999997, 4.99999999999986,0.11249999999998, 1.07995057924757e-27, 0.194444444444439),
                            Fvalue = c("1.0286","0.5786", "12.6", "130.1786", "25.7143", "0.5786", "0", ""), 
                            Pvalue = c("0.3139", "0.4494", "7e-04", "<0.0001", "<0.0001","0.4494", "1", ""),
                            Sig = c("", "", "***", "***", "***","", "", ""),
                            EMS = c("Error+40atm", "Error+40rzt", "Error+20atm:rzt","Error+40salt", "Error+20atm:salt", "Error+20rzt:salt", "Error+10atm:rzt:salt","Error")),
                       class = "data.frame",
                       row.names = c("atm", "rzt","atm:rzt", "salt", "atm:salt", "rzt:salt", "atm:rzt:salt", "Residuals"))
      req(aov_l)
      
      # 直接生成筛选后的字符向量
      int_sel <- rownames(head(aov_l,-1)) %>%
        keep(~str_count(.x, pattern = ":") > 1)
      
      disp<-TRUE
      int_title<-if(disp){
        "Show Three-Way Interaction Plots for Dispersion:"
      } else {
        "Show Three-Way Interaction Plots for Means:"
      }
      
      selectInput(inputId = "ems_int_selected",
                  label = int_title,
                  choices = int_sel,
                  multiple = TRUE,
                  width = "100%"
      )
    })
    
    output$selection<-renderText({
      input$ems_int_selected
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:34:53