简体   繁体   中英

R Shiny automating selectInput() features

In the app.R file below, I'm trying to create a selectInput() box for each column name of the iris dataset. However, I am not sure what must go in place of the ellipsis selectInput(..., 'Sepal.Length', c(0, 1)), in order to make it work, and I also don't like that I had to type out the name of the column itself. Of course, I could have done something like selectInput(..., 'names(iris)[1]', c(0, 1)), instead, but I'm looking to create something even more automated and streamlined (ie, writing out selectInput(..., 'column name', c(0, 1)), five times for each of the five columns seems grossly inefficient). In other words, perhaps I could make Shiny automatically recognize that the iris dataset has 5 columns by default, which would create the five selectInput() boxes appropriately?

The whole reason why I'm trying to accomplish this is because I would like to create a simple automated character vector (shown in the code below as vec <- c(1,1,0,0,1) #corresponding to c(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species) ), which automatically updates depending on whether I choose 0 or 1 in the respective selectInput() boxes discussed above.

Complete code (with critical sections marked with a hashtag):

  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)

Here is the use of 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')
  )
))

To retrieve the column names selected (1) and not selected (0), you can use the following options on the server side:

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

You could just use the multiple = TRUE value on the selectInput to allow for multiple columns to be selected. Then on your server side, you would just set vec <- as.numeric(names(iris) %in% input$iris_columns) where input$iris_columns refers to your selectInput element.

As an example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM