在一个shiny 的应用程序(RStudio)中,在server端,我有一个reactive,通过解析textInput的内容返回变量列表.然后在selectInput和/或updateSelectInput中使用变量列表.

我做不到.有什么建议吗?

我做了两次try .第一种方法是使用无功outVar直接转换成selectInput.第二种方法是使用updateSelectInput中的无功outVar.两者都不管用.

服务器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)
    })

})

用户界面.R

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

不久前,我在Shinny Discussion上发布了同样的问题,但没有引起多少兴趣,所以我再次提出https://groups.google.com/forum/#!topic/shiny-discuss/e0MgmMskfWo个问题,并表示歉意

Edit 1

@拉姆纳特很友好地发布了一个似乎有效的解决方案,由他表示为Edit 2.但这个解决方案并不能解决问题,因为textinputui面,而不是我的问题中的server面.如果我把Ramnath第二次编辑的textinput移到server边,问题又出现了,即:什么都不显示,RStudio崩溃.我发现用as.characterinput$text可以让问题消失.

Edit 2

在进一步的讨论中,Ramnath向我展示了当服务器在textinput返回其参数之前try 应用动态函数outVar时,问题会出现.解决方案是首先判断is.null(input$inBody)是否存在.

100,那我为什么没想到呢?是的,但我一定做错了什么!考虑到我花在这个问题上的时间,这是一次痛苦的经历.我在代码之后演示如何判断存在性.

下面是拉姆纳特的代码,textinput移到server边.它会让RStudio崩溃,所以不要在家里try .(我用过他的符号)

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)
}

这两种方法似乎都有效,但从现在起我将以拉姆纳特的方式进行:也许我的构造中的不平衡括号早些时候阻止了我进行判断?拉姆纳的判断更直接.

最后,我想指出一些关于我的各种调试try 的事情.

在我的调试任务中,我发现有一个选项可以对服务器端的"输出"优先级进行"排序",我试图解决我的问题,但由于问题在其他地方,所以没有起作用.尽管如此,了解这一点还是很有意思的,而且目前似乎还不是很广为人知:

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

在这一探索中,我还提到了tried try:

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

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

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

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

我想知道它为什么会起作用会很有趣:是因为它足够慢吗?是因为as.character"等待"input$text为非空吗?

不管是什么情况,我非常感谢拉姆纳特的努力、耐心和指导.

推荐答案

对于动态UI,您需要在服务器端使用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

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())
    })
  }
))

R相关问答推荐

Word中的分面图表

R根据名称的载体对收件箱列采取行动

当y大于阈值和值范围时,在时间序列中突出显示区域

rvest函数read_html_live()不允许html_elements()正确读取

基于两个现有列创建新列

生成具有受控相关性的x和y

在R中使用GG Plot时如何 suppress 等值线图中的彩色条

使用gggplot 2在R中重新调整面板和y轴文本大小

如何删除多个.CSV文件的行

即使硬币没有被抛出,也要保持对其的跟踪

R—将各种CSV数字列转换为日期

在多页PDF中以特定布局排列的绘图列表不起作用

调换行/列并将第一行(原始数据帧的第一列)提升为标题的Tidyr类似功能?

将项粘贴到向量中,并将它们分组为x的倍数,用空格分隔

使用来自嵌套列和非嵌套列的输入的PURRR:MAP和dplyr::Mariate

R中治疗序列的相对时间指数

用多边形替换地块点

如何在条形图中的x和填充变量中包含多个响应变量?

填充图例什么时候会有点?

使用函数从R中的列中删除标高