Rshiny传递反应selectInputselect

在一个shiny的应用程序(通过RStudio),在服务器端,我有一个反应,通过parsingtextInput的内容返回一个variables列表。 然后在selectInput和/或updateSelectInput使用variables列表。

我无法做到这一点。 有什么build议么?

我做了两次尝试。 第一种方法是将react nativeoutVar直接用于selectInput 。 第二种方法是使用updateSelectInput的react nativeoutVar 。 两者都行不通。

server.R

 shinyServer( function(input, output, session) { outVar <- reactive({ vars <- all.vars(parse(text=input$inBody)) vars <- as.list(vars) return(vars) }) output$inBody <- renderUI({ textInput(inputId = "inBody", label = h4("Enter a function:"), value = "a+b+c") }) output$inVar <- renderUI({ ## works but the choices are non-reactive selectInput(inputId = "inVar", label = h4("Select variables:"), choices = list("a","b")) }) observe({ ## doesn't work choices <- outVar() updateSelectInput(session = session, inputId = "inVar", choices = choices) }) }) 

ui.R

 shinyUI( basicPage( uiOutput("inBody"), uiOutput("inVar") ) ) 

不久之前,我在shiny的讨论中发表了同样的问题,但这并没有引起什么兴趣,所以我再次问道, https: //groups.google.com/forum/#! topic/shiny-讨论/ e0MgmMskfWo

编辑1

@Ramnath慷慨地发布了一个似乎可行的解决scheme,由他编辑2 。 但是这个解决scheme没有解决这个问题,因为textinput是在ui端,而不是在server端,因为它是在我的问题。 如果我将Ramnath的第二个编辑的文本input移动到server端,问题再次出现,即:没有任何显示和RStudio崩溃。 我发现在as.character中包装input$text会使问题消失。

编辑2

在进一步的讨论中,Ramnath告诉我,当服务器在textinput返回参数之前尝试使用outVardynamic函数时,会出现问题。 解决方法是首先检查是否存在is.null(input$inBody)

检查参数的存在是构build一个有光泽的应用程序的一个关键方面 ,所以为什么我没有想到呢? 那么,我做了,但我一定做错了! 考虑到我花在这个问题上的时间,这是一个痛苦的经历。 我在代码后显示如何检查存在。

下面是Ramnath的代码, textinput移到了server端。 它使RStudio崩溃,所以不要在家里尝试。 (我用他的符号)

 library(shiny) runApp(list( ui = bootstrapPage( uiOutput('textbox'), ## moving Ramnath's textinput to the server side uiOutput('variables') ), server = function(input, output){ outVar <- reactive({ vars <- all.vars(parse(text = input$text)) ## existence check needed here to prevent a crash vars <- as.list(vars) return(vars) }) output$textbox = renderUI({ textInput("text", "Enter Formula", "a=b+c") }) output$variables = renderUI({ selectInput('variables2', 'Variables', outVar()) }) } )) 

我通常检查存在的方式是这样的:

 if (is.null(input$text) || is.na(input$text)){ return() } else { vars <- all.vars(parse(text = input$text)) return(vars) } 

Ramnath的代码更短:

 if (!is.null(mytext)){ mytext = input$text vars <- all.vars(parse(text = mytext)) return(vars) } 

两者似乎都有效,但从现在开始我会这样做Ramnath的方式:也许我的构造中的一个不平衡的支架早已阻止我做检查工作? Ramnath的支票更直接。

最后,我想说明几个关于我的各种尝试debugging的事情。

在我的debugging任务中,我发现有一个选项可以在服务器端“排列”“输出”的优先级,我试图解决这个问题,但由于问题在其他地方,所以没有工作。 尽pipe如此,知道这件事很有意思,现在看起来并不是很有名:

 outputOptions(output, "textbox", priority = 1) outputOptions(output, "variables", priority = 2) 

在这个追求中,我也尝试过

 try(vars <- all.vars(parse(text = input$text))) 

这是非常接近,但仍然没有解决它。

我偶然发现的第一个解决scheme是:

 vars <- all.vars(parse(text = as.character(input$text))) 

我想知道它为什么起作用会很有趣:是因为它减慢了足够的速度? 这是因为as.character “等待” input$text是非空的吗?

无论如何,我非常感谢拉姆纳特的努力,耐心和指导。

您需要在服务器端使用dynamicUI的renderUI 。 这是一个最小的例子。 请注意,第二个下拉菜单是被动的,并根据您在第一个select的数据集进行调整。 代码应该是不言自明的,如果你之前已经处理了shiny。

 runApp(list( ui = bootstrapPage( selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')), uiOutput('columns') ), server = function(input, output){ output$columns = renderUI({ mydata = get(input$dataset) selectInput('columns2', 'Columns', names(mydata)) }) } )) 

编辑。 使用updateSelectInput另一个解决scheme

 runApp(list( ui = bootstrapPage( selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')), selectInput('columns', 'Columns', "") ), server = function(input, output, session){ outVar = reactive({ mydata = get(input$dataset) names(mydata) }) observe({ updateSelectInput(session, "columns", choices = outVar() )}) } )) 

EDIT2:使用parse修改示例。 在这个应用程序中,input的文本公式用于dynamic填充下面的variables列表下拉菜单。

 library(shiny) runApp(list( ui = bootstrapPage( textInput("text", "Enter Formula", "a=b+c"), uiOutput('variables') ), server = function(input, output){ outVar <- reactive({ vars <- all.vars(parse(text = input$text)) vars <- as.list(vars) return(vars) }) output$variables = renderUI({ selectInput('variables2', 'Variables', outVar()) }) } )) 

据我所知,问题是即使selectInput函数被赋予一个character作为值,即input$inBody不会检索一个character ,即value = "a+b+c" 。 因此,解决scheme是将input$inBody as.character

以下工作:

使用updateSelectInputobserve方法:

 observe({ input$inBody vars <- all.vars(parse(text=as.character(input$inBody))) vars <- as.list(vars) updateSelectInput(session = session, inputId = "inVar", choices = vars) }) 

使用selectInputreactive方法:

 outVar <- reactive({ vars <- all.vars(parse(text=as.character(input$inBody))) vars <- as.list(vars) return(vars) }) output$inVar2 <- renderUI({ selectInput(inputId = "inVar2", label = h4("Select:"), choices = outVar()) }) 

编辑:我已经编辑我的问题,根据Ramnath的反馈解释。 拉姆纳特已经解释了这个问题,提供了一个更好的解决scheme,我把这个问题作为编辑。 我会保留这个答案,但不值得投票。

server.R

 ### This will create the dynamic dropdown list ### output$carControls <- renderUI({ selectInput("cars", "Choose cars", rownames(mtcars)) }) ## End dynamic drop down list ### ## Display selected results ## txt <- reactive({ input$cars }) output$selectedText <- renderText({ paste("you selected: ", txt() ,sep="") }) ## End Display selected results ## 

ui.R

 uiOutput("carControls"), br(), textOutput("selectedText")