R闪亮的传递反应到selectInput选择 [英] R shiny passing reactive to selectInput choices
问题描述
在一个闪亮的应用程序(由 RStudio 开发)中,在 服务器 端,我有一个反应式,它通过解析 textInput
的内容返回变量列表.然后在 selectInput
和/或 updateSelectInput
中使用变量列表.
In a shiny app (by RStudio), on the server side, I have a reactive that returns a list of variables by parsing the content of a textInput
. The list of variables is then used in selectInput
and/or updateSelectInput
.
我不能让它工作.有什么建议吗?
I can't make it work. Any suggestions?
我做了两次尝试.第一种方法是将反应式 outVar
直接用于 selectInput
.第二种方法是在 updateSelectInput
中使用反应式 outVar
.两个都不行.
I have made two attempts. The first approach is to use the reactive outVar
directly into selectInput
. The second approach is to use the reactive outVar
in updateSelectInput
. Neither works.
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-discuss 上发布了同样的问题,但它引起的兴趣不大,所以我再次问,抱歉,https://groups.google.com/forum/#!topic/shiny-discuss/e0MgmMskfWo
A short while ago, I posted the same question at shiny-discuss, but it has generated little interest, so I'm asking again, with apologies, https://groups.google.com/forum/#!topic/shiny-discuss/e0MgmMskfWo
编辑 1
@Ramnath 好心地发布了一个似乎有效的解决方案,由他表示 Edit 2.但该解决方案并没有解决问题,因为 textinput
位于 ui
端,而不是在我的问题中的 server
端.如果我将 Ramnath 的第二次编辑的 textinput
移动到 server
端,问题再次出现,即:没有任何显示并且 RStudio 崩溃.我发现将 input$text
包裹在 as.character
中会使问题消失.
@Ramnath has kindly posted a solution that appears to work, denoted Edit 2 by him. But that solution does not address the problem because the textinput
is on the ui
side instead of on the server
side as it is in my problem. If I move the textinput
of Ramnath's second edit to the server
side, the problem crops up again, namely: nothing shows and RStudio crashes. I found that wrapping input$text
in as.character
makes the problem disappear.
编辑 2
在进一步的讨论中,Ramnath 向我展示了当服务器尝试在 textinput
返回其参数之前应用动态函数 outVar
时会出现问题.解决办法是先检查is.null(input$inBody)
是否存在
In further discussion, Ramnath has shown me that the problem arises when the server attempts to apply the dynamic function outVar
before its arguments have been returned by textinput
. The solution is to first check whether is.null(input$inBody)
exists.
检查参数是否存在是构建闪亮应用的一个重要方面,那么我为什么没有想到呢?好吧,我做到了,但我一定是做错了什么!考虑到我在这个问题上花费的时间,这是一次痛苦的经历.我在代码后面展示了如何检查是否存在.
Checking for existence of arguments is a crucial aspect of building a shiny app, so why did I not think of it? Well, I did, but I must have done something wrong! Considering the amount of time I spent on the problem, it's a bitter experience. I show after the code how to check for existence.
下面是 Ramnath 的代码,其中 textinput
移到了 server
端.它会导致 RStudio 崩溃,所以不要在家里尝试.(我用过他的记法)
Below is Ramnath's code with textinput
moved to the server
side. It crashes RStudio so don't try it at home. (I have used his notation)
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())
})
}
))
我通常检查存在的方式是这样的:
The way I usually check for existence is like this:
if (is.null(input$text) || is.na(input$text)){
return()
} else {
vars <- all.vars(parse(text = input$text))
return(vars)
}
Ramnath 的代码更短:
Ramnath's code is shorter:
if (!is.null(mytext)){
mytext = input$text
vars <- all.vars(parse(text = mytext))
return(vars)
}
两者似乎都有效,但从现在开始我将按照 Ramnath 的方式进行:也许我的构造中的不平衡括号早些时候阻止了我进行检查?Ramnath 的过牌更直接.
Both seem to work, but I'll be doing it Ramnath's way from now on: maybe an unbalanced bracket in my construct had earlier prevented me to make the check work? Ramnath's check is more direct.
最后,我想说明一些关于我的各种调试尝试的事情.
Lastly, I'd like to note a couple of things about my various attempts to debug.
在我的调试任务中,我发现有一个选项可以在服务器端对输出"的优先级进行排序",我试图解决我的问题,但由于问题出在别处.不过,了解这一点很有趣,而且目前似乎还不太为人所知:
In my debugging quest, I discovered that there is an option to "rank" the priority of "outputs" on the server side, which I explored in an attempt to solve my problem, but didn't work since the problem was elsewhere. Still, it's interesting to know and seems not very well known at this time:
outputOptions(output, "textbox", priority = 1)
outputOptions(output, "variables", priority = 2)
在那个任务中,我也尝试 try
:
In that quest, I also tried try
:
try(vars <- all.vars(parse(text = input$text)))
那已经很接近了,但仍然没有修复它.
That was pretty close, but still did not fix it.
我偶然发现的第一个解决方案是:
The first solution I stumbled upon was:
vars <- all.vars(parse(text = as.character(input$text)))
我想知道它为什么起作用会很有趣:是因为它足够减慢速度吗?是不是因为 as.character
等待" input$text
为非空?
I suppose it would be interesting to know why it worked: is it because it slows things down enough? is it because as.character
"waits" for input$text
to be non-null?
无论情况如何,我都非常感谢 Ramnath 的努力、耐心和指导.
Whatever the case may be, I am extremely grateful to Ramnath for his effort, patience and guidance.
推荐答案
您需要在服务器端使用 renderUI
来实现动态 UI.这是一个最小的例子.请注意,第二个下拉菜单是反应式的,会根据您在第一个下拉菜单中选择的数据集进行调整.如果您之前处理过 Shiny,代码应该是不言自明的.
You need to use renderUI
on the server side for dynamic UIs. Here is a minimal example. Note that the second drop-down menu is reactive and adjusts to the dataset you choose in the first one. The code should be self-explanatory if you have dealt with shiny before.
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()
)})
}
))
使用 parse
修改的示例.在此应用中,输入的文本公式用于使用变量列表动态填充下面的下拉菜单.
Modified Example using parse
. In this app, the text formula entered is used to dynamically populate the dropdown menu below with the list of 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())
})
}
))
这篇关于R闪亮的传递反应到selectInput选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!