【问题标题】:R Shiny automating selectInput() featuresR Shiny 自动化 selectInput() 功能
【发布时间】:2016-01-04 16:41:07
【问题描述】:

在下面的 app.R 文件中,我尝试为 iris 数据集的每个列名称创建一个 selectInput() 框。但是,我不确定必须用什么代替省略号 selectInput(..., 'Sepal.Length', c(0, 1)), 才能使其正常工作,而且我也不喜欢我必须输入列本身的名称。当然,我本可以改用selectInput(..., 'names(iris)[1]', c(0, 1)), 之类的东西,但我希望创建一些更加自动化和简化的东西(即,为五列中的每一列写出selectInput(..., 'column name', c(0, 1)), 五次似乎非常低效)。换句话说,也许我可以让 Shiny 自动识别 iris 数据集默认有 5 列,这样可以适当地创建五个 selectInput() 框?

我尝试完成此操作的全部原因是因为我想创建一个简单的自动字符向量(在下面的代码中显示为vec <- c(1,1,0,0,1) #corresponding to c(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species)),它会根据我选择01 在上面讨论的各个 selectInput() 框中。

完整代码(关键部分标有井号):

  palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
  "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))

server <- shinyServer(function(input, output, session) {

  # Combine the selected variables into a new data frame
  selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })

  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })

  output$plot1 <- renderPlot({
    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
         col = clusters()$cluster,
         pch = 20, cex = 3)
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })

  #vec <- c(1,1,0,0,1)  #corresponding to c(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species)

})


ui <- shinyUI(pageWithSidebar(
  headerPanel('Iris k-means clustering'),
  sidebarPanel(
    selectInput('xcol', 'X Variable', names(iris)),
    selectInput('ycol', 'Y Variable', names(iris),
                selected=names(iris)[[2]]),
    #selectInput(..., 'Sepal.Length', c(0, 1)),
    #selectInput(..., 'Sepal.Width', c(0, 1)),
    #selectInput(..., 'Petal.Length', c(0, 1)),
    #selectInput(..., 'Petal.Width', c(0, 1)),
    #selectInput(..., 'Species', c(0, 1)),
    numericInput('clusters', 'Cluster count', 3,
                 min = 1, max = 9)
  ),
  mainPanel(
    plotOutput('plot1')
  )
))


# Return a Shiny app object
shinyApp(ui = ui, server = server)

【问题讨论】:

  • 可以在UI端使用renderUI,然后在服务端生成selectInput。实际上,按如下方式使用它会起作用:selectInput('columnName', 'Column Name', names(iris))。您是否有理由尝试为每个列名创建单独的下拉列表?
  • 我正在尝试为每个列名创建一个单独的下拉列表,以便我可以输入字符向量 vec &lt;- c(1,1,0,0,1)(即,我可以将其设为 c(0,0,1,0,1)c(1,0,0,0,0)或其他,基于我在下拉菜单中选择的内容)
  • 如果您想选择某些列,为什么不使用multiple = TRUE 设置selectInput,然后根据选择的选项设置vec
  • @brittenb 你能证明作为答案吗?这听起来很有希望。
  • 如果您希望能够同时选择多个值,我建议使用“checkboxGroupInput”,因为它是更合适的 UI 元素。是的,selectInput 中的 multiple = TRUE 也将允许这样做,但在我看来,这不是这个用例的正确选择。

标签: r shiny


【解决方案1】:

您可以只使用selectInput 上的multiple = TRUE 值来允许选择多个列。然后在您的服务器端,您只需设置vec &lt;- as.numeric(names(iris) %in% input$iris_columns),其中input$iris_columns 指的是您的selectInput 元素。

举个例子:

ui <- shinyUI(pageWithSidebar(
  headerPanel('Iris k-means clustering'),
  sidebarPanel(
    selectInput('xcol', 'X Variable', names(iris)),
    selectInput('ycol', 'Y Variable', names(iris), selected=names(iris)[[2]]),
    selectInput('iris_columns', 'Select Columns', choices = names(iris), multiple = TRUE),
    numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
  ),
  mainPanel(
    plotOutput('plot1')
  )
))

server <- shinyServer(function(input, output, session) {

  # Combine the selected variables into a new data frame
  selectedData <- reactive({
    iris[, c(input$xcol, input$ycol)]
  })

  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })

  output$plot1 <- renderPlot({
    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
         col = clusters()$cluster,
         pch = 20, cex = 3)
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })

  vec <- as.numeric(names(iris) %in% input$iris_columns)
})

【讨论】:

  • 是的,但是在这里您需要手动输入c(1,3,4)...希望您可以改为使用selectInput()checkboxGroupInput() 勾选框(或复选框)
  • 不,这只是一个示例,表明如果x 是来自iris 的列名向量,那么像我们所做的那样设置vec 会给你结果。在应用程序的 UI 端,您可以将其设置为 selectInput('iris_columns', 'Select Columns', choices = names(iris), multiple = TRUE)。然后,一旦用户选择了他们的选择,vec 就会被更新。无需输入任何内容。
  • 好的,请随时更新您的完整答案,如果可行,我将对其进行测试/接受。
  • 是的,但是上面代码中给出的 0/1 名称在哪里?
  • 根据需要保存在vec
【解决方案2】:

这里是checkboxGroupInput的使用:

ui <- shinyUI(pageWithSidebar(
  headerPanel('Iris k-means clustering'),
  sidebarPanel(
    selectInput('xcol', 'X Variable', names(iris)),
    selectInput('ycol', 'Y Variable', names(iris),
                selected=names(iris)[[2]]),
    checkboxGroupInput('columnNames', 'Column Name', names(iris)),
    numericInput('clusters', 'Cluster count', 3,
                 min = 1, max = 9)
  ),
  mainPanel(
    plotOutput('plot1')
  )
))

要检索已选择 (1) 和未选择 (0) 的列名,您可以在服务器端使用以下选项:

> s <- c('Sepal.Length', 'Sepal.Width', 'Petal.Width') # Example vector from checkbox group input
> names(iris) %in% s
[1]  TRUE  TRUE FALSE  TRUE FALSE
> as.integer(names(iris) %in% s)
[1] 1 1 0 1 0
> which(names(iris) %in% s) # Provides vector indices set to 1
[1] 1 2 4
> which(!names(iris) %in% s) # Provides vector indices set to 0
[1] 3 5
> 

【讨论】:

  • 是的,但是当我选中其中一个列名时,它实际上并没有将 0 或 1 返回到字符向量中。
  • 我想一个选项可以默认将所有内容指定为 0,然后检查您希望成为 1 的任何列名。这可能是一种潜在的解决方法,但您需要将答案更新为反映这一点。
  • 在服务器端使用 names(iris) %in% input$columnNames 会给你一个选择的列名向量(布尔值 TRUE/FALSE 值)。这行得通吗?我可以更新答案。
  • 实际上可能,特别是如果您将 TRUE 指定为 1 并将 FALSE 指定为 0(反之亦然)
猜你喜欢
  • 1970-01-01
  • 2020-09-14
  • 2021-08-04
  • 2018-06-30
  • 2017-02-18
  • 2020-12-25
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多