动态列出选项' for userInput from user selected column

时间:2017-11-12 12:00:03

标签: r dynamic shiny shiny-reactivity

selectInput()的列表选项是通过对值进行硬编码来完成的,如?selectInput中的示例所示:

selectInput(inputID = "variable", label ="variable:",
                choices = c("Cylinders" = "cyl",
                  "Transmission" = "am",
                  "Gears" = "gear"))

但是,我希望我的choices列表是来自用户选择的列的唯一列表,这些列来自用户上传的文件(csv)。我怎么能这样做?就我而言:

UI

    shinyUI(fluidPage(
          fluidRow(
                   fileInput('datafile', 'Choose CSV file',
                accept=c('text/csv', 'text/comma-separated-values,text/plain')),
                   uiOutput("selectcol10"),
                   uiOutput("pic")
    ))
)

服务器

    shinyServer(function(input, output) {

  filedata <- reactive({
    infile <- input$datafile
    if (is.null(infile)) {
      # User has not uploaded a file yet
      return(NULL)
    }
    temp<-read.csv(infile$datapath)
    #return
    temp[order(temp[, 1]),]
  })

  output$selectcol10 <- renderUI({
    df <-filedata()
    if (is.null(df)) return(NULL)

    items=names(df)
    names(items)=items
    selectInput("selectcol10", "Primary C",items) 
  })

  col10 <- reactive({
    (unique(filedata()$selectcol10))
  })

  output$pic <- renderUI({
    selectInput("pic", "Primary C values",col10())
  })
})

2 个答案:

答案 0 :(得分:9)

对于动态用户界面,您基本上可以选择两种路线:updateXXXrenderUI。这是采用updateXXX方法的解决方案。

library(shiny)

ui <- fluidPage(sidebarLayout(
  sidebarPanel(
    selectInput("dataset", "choose a dataset", c("mtcars", "iris")),
    selectInput("column", "select column", "placeholder1"),
    selectInput("level", "select level", "placeholder2")
  ),
  mainPanel(tableOutput("table"))
))

server <- function(input, output, session){
  dataset <- reactive({
    get(input$dataset)
  })

  observe({
    updateSelectInput(session, "column", choices = names(dataset())) 
  })

  observeEvent(input$column, {
    column_levels <- as.character(sort(unique(
      dataset()[[input$column]]
    )))
    updateSelectInput(session, "level", choices = column_levels)
  })

  output$table <- renderTable({
    subset(dataset(), dataset()[[input$column]] == input$level)
  })
}

shinyApp(ui, server)

server函数中,有一行

updateSelectInput(session, "level", choices = column_levels)

更新第三个下拉菜单choices的{​​{1}}参数。要计算级别,您可以使用level函数, 不适用于numerc列。因此我用了

base::levels

代替。 “占位符”将在启动后立即更换。

app screenshot

使用fileInput

创建的数据帧

下面的代码显示了如何将此逻辑与as.character(sort(unique( . ))) 结合使用。只要没有选择文件,我在fileInput中添加了conitionalPanel来隐藏下拉菜单。请参阅here

ui

答案 1 :(得分:0)

这是有效的,并且归功于@GregordeCillia引导我:

在SERVER中我取代了

col10 <- reactive({
    (unique(filedata()$selectcol10))
  })

  output$pic <- renderUI({
    selectInput("pic", "Primary C values",col10())
  })

  observe({
    valu <- unique(unlist(filedata()[input$selectcol10]))
    updateSelectInput(session, "level", choices = valu)
  })

在UI中我替换了

uiOutput("pic")

selectInput("level", "select level", "placeholder")),