在一个闪亮的应用程序(由RStudio),在服务器端,我有一个反应,通过解析a的内容返回变量列表textInput
.然后在selectInput
和/或中使用变量列表updateSelectInput
.
我不能让它发挥作用.有什么建议?
我做了两次尝试.第一种方法是outVar
直接使用反应selectInput
.第二种方法是使用反应性outVar
在updateSelectInput
.两者都不起作用.
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) }) })
shinyUI( basicPage( uiOutput("inBody"), uiOutput("inVar") ) )
不久之前,我在发光讨论中发布了同样的问题,但它引起的兴趣不大,所以我再次问道,道歉,https: //groups.google.com/forum/#!topic/shiny-讨论/ e0MgmMskfWo
编辑1
@Ramnath亲切地发布了一个似乎有效的解决方案,由他表示为Edit 2.但由于该解决方案并没有解决这个问题textinput
是在ui
侧面,而不是在server
一边,因为它是我的问题.如果我将textinput
Ramnath的第二个编辑移到server
一边,问题再次出现,即:没有任何显示,RStudio崩溃.我发现,包裹input$text
在as.character
使问题消失.
编辑2
在进一步的讨论中,Ramnath向我展示了当服务器outVar
在其参数返回之前尝试应用动态函数时出现问题textinput
.解决方案是首先检查是否is.null(input$inBody)
存在.
检查参数的存在是构建一个闪亮的应用程序的一个重要方面,所以为什么我没有想到它?嗯,我做到了,但我一定做错了!考虑到我花在这个问题上的时间,这是一个痛苦的经历.我在代码后显示如何检查是否存在.
下面是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的方式:也许我的构造中的一个不平衡的支架早先阻止我进行检查工作?拉姆纳特的支票更直接.
最后,我想说明一些关于我的各种调试尝试的事情.
在我的调试任务中,我发现有一个选项可以"排列"服务器端"输出"的优先级,我试图解决我的问题,但是由于问题出在其他地方而无法工作.尽管如此,知道并且目前看来并不是很有名,这很有趣:
outputOptions(output, "textbox", priority = 1) outputOptions(output, "variables", priority = 2)
在那个任务中,我也尝试过 try
:
try(vars <- all.vars(parse(text = input$text)))
那是非常接近的,但仍然没有解决它.
我偶然发现的第一个解决方案是:
vars <- all.vars(parse(text = as.character(input$text)))
我想知道它为什么会起作用会很有趣:是不是因为它减慢了足够的速度?是因为as.character
"等待" input$text
非空?
无论情况如何,我都非常感谢Ramnath的努力,耐心和指导.
您需要renderUI
在服务器端使用动态UI.这是一个最小的例子.请注意,第二个下拉菜单是被动的,并根据您在第一个选择的数据集进行调整.如果您之前处理过闪亮的代码,那么代码应该是不言自明的.
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
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
.在此应用程序中,输入的文本公式用于使用变量列表动态填充下面的下拉菜单.
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()) }) } ))