R闪亮的传递反应到selectInput选择 [英] R shiny passing reactive to selectInput choices

查看:50
本文介绍了R闪亮的传递反应到selectInput选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个闪亮的应用程序(由 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆