Shiny中updateSelectInput更新后第二个selectInput值重复问题排查
问题成因
该问题由dplyr的非标准评估机制导致,核心原因如下:
input$filtro返回的是字符串格式的列名,例如选中第一个下拉框的「Servicio」时,input$filtro的取值就是字符串"Servicio"- 直接将字符串变量传入
group_by()时,dplyr不会将其解析为数据框对应的实际列,而是会把它当作固定字符串常量作为分组依据,最终只会得到1组结果,组名就是传入的字符串本身 - 因此计算得到的
example()$Valor永远只有一个值,即第一个下拉框选中的列名字符串,自然第二个下拉框的选项就和第一个选中值完全一致
修复方案
只需调整group_by()的动态列名传参方式,将字符串列名转为dplyr可识别的符号即可,常用实现方案有两种:
方案1:使用!!解引用(推荐,适配dplyr 1.0及以上版本)
用sym()将字符串列名转为符号,再用!!解引用传入group_by(),修改后的完整服务端代码如下:
server <- function(input, output, session) { example <- reactive({ data |> group_by(!!sym(input$filtro)) |> summarise(n = n()) |> setNames(c("Valor", "Valor2")) |> select(Valor) }) observe({ req(example()) updateSelectInput(session, "filtro_final", choices = example()$Valor) }) }
方案2:使用group_by_at(适配旧版dplyr)
如果使用的是1.0以下版本的dplyr,也可以直接用group_by_at()接收字符串格式的列名:
example <- reactive({ data |> group_by_at(input$filtro) |> summarise(n = n()) |> setNames(c("Valor", "Valor2")) |> select(Valor) })
修改后运行即可实现预期效果:第一个下拉选「Servicio」时第二个下拉选项为serv1、serv2,选「Subservicio」时第二个下拉选项为sub1、sub2、sub3。
内容的提问来源于stack exchange,提问作者Jorge Hernández
相关产品推荐
相关产品推荐

