从用户选择的列中动态列出selectInput的“选择” [英] dynamically list 'choices' for selectInput from a user selected column

查看:96
本文介绍了从用户选择的列中动态列出selectInput的“选择”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Listing choices for selectInput() is done by hardcoding the values, as in the example from ?selectInput:

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

但是,我希望选择列表是来自文件的用户选择列中值的唯一列表( csv)由用户上传。我该怎么办?据我所知:

However, I'd like my list of choices to be a unique listing of values from a user-selected column coming from a file (csv) uploaded by the user. How might I do this? This is as far as I've gotten:

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


推荐答案

对于动态UI基本上您可以采用两种方法: updateXXX renderUI 。这是采用 updateXXX 方法的解决方案。

For dynamic UIs there are basically two routes you can take: updateXXX or renderUI. Here is a solution that takes the updateXXX approach.

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)

服务器函数中,有一行

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

会更新<$第三个下拉菜单 level 的c $ c> choices 自变量。要计算级别,可以使用 base :: levels 函数,但是 不适用于numerc列。因此,我使用

which updates the choices argument of the third dropdown menu level. To calculate levels, you can use the base::levels function, but that does not work for numerc columns. Therefore I used

as.character(sort(unique( . )))

。启动后将立即替换占位符。

instead. The "placeholders" will be replaced immediately after startup.

创建的数据帧下面的代码显示了如何将此逻辑与 fileInput 组合。我在 ui 中添加了 conitionalPanel ,以隐藏下拉菜单,只要未选择任何文件。请参见此处

The code below shows how this logic can be combined with fileInput. I added a conitionalPanel in the ui to hide the dropdown-menus as long as no file is selected. See here.

library(shiny)

# test data
write.csv(reshape2::tips, "tips.csv", row.names = FALSE)
write.csv(mtcars, "mtcars.csv")

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput('datafile', 'Choose CSV file',
                accept = c('text/csv', 'text/comma-separated-values,text/plain', '.csv')),
      conditionalPanel(
        # use a server side condition
        condition = "output.fileUploaded",
        # placeholders will be replaced from the server
        selectInput("pic", "Primay C", "placeholder 1"),
        selectInput("level", "select level", "placeholder 2")
      )
    ),
    mainPanel(
      h3("filtered data"),
      tableOutput("table")
    )
  )
)

server <- function(input, output, session){
  # create reactive version of the dataset (a data.frame object)
  filedata <- reactive({
    infile <- input$datafile
    if (is.null(infile))
      # User has not uploaded a file yet. Use NULL to prevent observeEvent from triggering
      return(NULL)
    temp <- read.csv(infile$datapath)
    temp[order(temp[, 1]),]
  })

  # inform conditionalPanel wheter dropdowns sohould be hidden
  output$fileUploaded <- reactive({
    return(!is.null(filedata()))
  })
  outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)

  # update the selectInput elements according to the dataset

  ## update 'column' selector
  observeEvent(filedata(), {
    updateSelectInput(session, "pic", choices = names(filedata()))
  })

  ## update 'level' selector
  observeEvent(input$pic, {
    column_levels <- unique(filedata()[[input$pic]])
    updateSelectInput(session, "level", choices = column_levels,
                      label = paste("Choose level in", input$pic))
  }, ignoreInit = TRUE)

  # show table
  output$table <- renderTable({
    subset(filedata(), filedata()[[input$pic]] == input$level)
  }, bordered = TRUE)
}

shinyApp(ui, server)

这篇关于从用户选择的列中动态列出selectInput的“选择”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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