在 服务器这边的一个闪亮的应用程序(由 RStudio 开发)中,我有一个反应器,它通过解析 textInput
的内容来返回一个变量列表。然后在 selectInput
和/或 updateSelectInput
中使用变量列表。
我做不到,有什么建议吗?
我已经试过两次了。第一种方法是使用反应性 outVar
直接进入 selectInput
。第二种方法是在 updateSelectInput
中使用反应性 outVar
。都不管用。
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-discuss/e0MgmMskfWo
编辑1
@ Ramnath 友好地贴出了一个看起来可行的解决方案,由他表示为 编辑2。但是这个解决方案并没有解决问题,因为 textinput
是在 ui
而不是在 server
一边,因为它是在我的问题。如果我将 Ramnath 第二次编辑的 textinput
移动到 server
端,问题又出现了,即: 没有显示任何内容,RStudio 崩溃。我发现在 as.character
中包装 input$text
可以使问题消失。
编辑2
在进一步的讨论中,Ramnath 向我展示了当服务器在其参数被 textinput
返回之前试图应用动态函数 outVar
时出现的问题。解决方案是首先检查 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 的方法来做: 也许我的构造中的一个不平衡的括号早些时候阻止了我使检查起作用?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 的努力、耐心和指导。