shiny using selectizeInput to build dynamic data o

2019-09-07 22:53发布

问题:

The inputs are displayed in "iris$Petal.Width - iris$Species" format.Upon selected inputs, data to be split and iris$Petal.Width alone to be used to filter entire data. Example: selected values are as in the image.

Try to get data like dplyr::filter(iris,iris$Petal.Width %in% c('0.2','0.3','0.1','0.6','1.4')) How to form the c('0.2','0.3','0.1','0.6','1.4') dynamically.

Taken this example for easy understanding, actually the inputs are in A001 - Description1, A002 - Description2 format. Need to take A001, A002 to form c('A001','A002').

Tried with below code:

## run in interactive R sessions
if (interactive()) {

  ui <- fluidPage(

    selectizeInput('ipdesc', label='Selector', 
                   choices = as.list(c(unique(paste(iris$Petal.Width,iris$Species,sep = " - ")))),
                   multiple = TRUE,
                   options = list(maxItems = 5)
    ),
    p("Select Codes (Max 5), then press 'Go'"),
    actionButton("go", label = "Go"),
    tableOutput("selected")
  )

  server <- function(input, output) {
    #
    output$selected <- renderTable({
      filterdata()
    })

    filterdata <- eventReactive(input$go,{
      x=c()
      cnt = length(input$ipdesc)
      for (i in 1:cnt){
        if (i != cnt) {
          x[i] = cat(sapply(strsplit(input$ipdesc[i], " - "), "[", 1),",")
        }
        else
        {x[i] = cat(x[1],sapply(strsplit(input$ipdesc[i], " - "), "[", 1))}

      } })


    #

  }

  shinyApp(ui, server)

}

回答1:

This isn't really a shinyapps or shinyjs question, all you need to know is how to match split a string to match part of it to a data frame. Because you're working with data frames, strsplit() may not be the most elegant solution.

As you mention dplyr, I will give you a tidyverse option:

Try using separate() from the tidyr package. convert = TRUE means that the resulting columns should be automatically converted to numeric/integer/logical if possible.

library(dplyr)
library(tidyr)

input <- "1.8 - versicolor"

temp <- data.frame(input = input) %>%
          tidyr::separate(input, c("Petal.Width", "Species"), 
                          sep = " - ", convert = TRUE)
filtered <- dplyr::filter(iris, iris$Petal.Width %in% temp$Petal.Width)

filtered output:

#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 1           5.9         3.2          4.8         1.8 versicolor
# 2           6.3         2.9          5.6         1.8  virginica
# 3           7.3         2.9          6.3         1.8  virginica
# 4           6.7         2.5          5.8         1.8  virginica
# 5           6.5         3.0          5.5         1.8  virginica
# ...

Note that this matches both versicolor and virginica.

Combined with your shiny script:

library(shiny)
if (interactive()) {

  ui <- fluidPage(
    selectizeInput('ipdesc', label='Selector', 
                   choices = as.list(c(unique(paste(iris$Petal.Width,iris$Species,sep = " - ")))),
                   multiple = TRUE,
                   options = list(maxItems = 5)
    ),
    p("Select Codes (Max 5), then press 'Go'"),
    actionButton("go", label = "Go"),
    tableOutput("selected")
  )

  server <- function(input, output) {

    output$selected <- renderTable({
      filterdata()
    })

    filterdata <- eventReactive(input$go, {
      temp <- data.frame(input = input$ipdesc) %>%
        tidyr::separate(input, c("Petal.Width", "Species"), sep = " - ", convert = TRUE)

       iris %>%
         dplyr::filter(iris$Petal.Width %in% temp$Petal.Width)

    })    
  }

  shinyApp(ui, server)

}


标签: r shiny shinyjs