Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
593 views
in Technique[技术] by (71.8m points)

dplyr - R Shiny | Chaining input choices to group a dataframe

I'm writing a shiny app that will help my colleagues to inspect csv files a bit closer.

The first tab allows for import, and the second for grouping of data.

For ease of coding, if no csv is uploaded, it uses the mtcars data set.

It takes a dataset, and then writes summaries based on selected columns and groupings.

I've managed to develop a reactive input which takes the columns you would like to select. The grouping input is then updated with only those the 'selected' columns as choices. However, it does not seem pass this to the function which creates the summary output. It creates a warning:

Warning: Error in : Must subset columns with a valid subscript vector. x Subscript has the wrong type list. ? It must be numeric or character. 119:

The hashed code causes the shiny app to crash.

library(shiny)
library(DT)
library(dplyr)

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

    myData <-reactive({
        if(is.null(input$file1)) return(mtcars)
        as.data.frame(rbindlist(lapply(X=input$file1$datapath, FUN=read.csv,
                  quote=input$quote, sep=input$sep, header=input$header, dec=input$decimal),
                  use.names = TRUE,fill=TRUE
        ))
    })

    output$contents <-
            DT::renderDataTable({
        return(DT::datatable(myData(), filter='top'))
            })

    observe({
        data <- myData()
        updateSelectInput(session, 'selected',choices=names(data))
    })


#    observeEvent(input$selected, {
#        data <- myData() %>% select(all_of(input$selected))
#        updateSelectInput(session, 'groupby', choices= names(data))
#    })



    output$group_summary <- renderPrint({
        myData() %>%
            select(all_of(input$selected)) %>%
            group_by(across(all_of(input$groupby))) %>%
            summary()

    })



}
)


ui <- shinyUI(fluidPage(


    titlePanel("Nya Statistikhanteraren"),
            # Input: Select a file ----
    navlistPanel(
        tabPanel("Import",
                fileInput("file1", "Choose CSV File",
                          multiple = TRUE,
                          accept = c("text/csv",
                                     "text/comma-separated-values,text/plain",
                                     ".csv")),

            # Horizontal line ----
                tags$hr(),

            # Input: Checkbox if file has header ----
                checkboxInput("header", "Header", TRUE),

            # Input: Select separator ----
                radioButtons("sep", "Separator",
                            choices = c(Comma = ",",
                                        Semicolon = ";",
                                        Tab = ""),
                            selected = ""),

            # Input: Select quotes ----
                radioButtons("quote", "Quote",
                            choices = c(None = "",
                                        "Double Quote" = '"',
                                        "Single Quote" = "'"),
                            selected = '"'),

            # Input: Select decimal ----

            radioButtons("decimal","Decimal",
                         choices = c(Comma = ",",
                                     Dot = "."),
                         selected=","),

            # Horizontal line ----
                tags$hr(),

    # Main panel for displaying outputs ----


            # Output: Data file ----
                DT::dataTableOutput("contents")
        ),
    tabPanel("Grouping",

             varSelectInput("selected", "Selected:", data, multiple = TRUE),
             varSelectInput("groupby", "Grouping:", data, multiple=TRUE),

             box(
                 title="Summary",
                 status="warning",
                 solidHeader=TRUE,
                 verbatimTextOutput("group_summary")
             )
             )
    )
  )
)

shinyApp(ui,server)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think this is more in line with what you want. The main problem with the selectors is that they were returning lists and all_of() wanted a vector, so wrapping input$selected in as.character() solved that problem. The other problem that you would encounter is that the summary that was being generated wasn't affected by the group_by() statement. I modified that part of the function so you would get a summary for each group in your group_by argument. There is still a labels missing warning, but I suspect you can troubleshoot that.

library(shiny)
library(DT)
library(dplyr)

server <- shinyServer(function(input, output, session){
  #     Add to your server
  observeEvent(input$browser,{
      browser()
  })
  
  myData <-reactive({
    if(is.null(input$file1)) return(mtcars)
    as.data.frame(rbindlist(lapply(X=input$file1$datapath, FUN=read.csv,
                                   quote=input$quote, sep=input$sep, header=input$header, dec=input$decimal),
                            use.names = TRUE,fill=TRUE
    ))
  })
  
  output$contents <-
    DT::renderDataTable({
      return(DT::datatable(myData(), filter='top'))
    })
  
  observe({
    data <- myData()
    updateSelectInput(session, 'selected',choices=names(data))
  })
  
  
     observeEvent(input$selected, {
         data <- myData() %>% dplyr::select(all_of(as.character(input$selected)))
         updateSelectInput(session, 'groupby', choices= names(data))
     })
  
  
  
  output$group_summary <- renderPrint({
    if(length(input$groupby) >0){
    tmp <- myData() %>%
      dplyr::select(all_of(as.character(input$selected))) %>%
      group_by(across(all_of(as.character(input$groupby))))
    tk <- tmp %>% group_keys
    tk <- tk %>% as.matrix() %>% apply(1, paste, collapse="-")
    tmp <- tmp %>% group_split() %>% setNames(tk)
    lapply(tmp, summary)
    }
  }, width=600)
  
  
  
}
)


ui <- shinyUI(fluidPage(
  
  
  titlePanel("Nya Statistikhanteraren"),
  # Input: Select a file ----
  navlistPanel(
    tabPanel("Import",
             fileInput("file1", "Choose CSV File",
                       multiple = TRUE,
                       accept = c("text/csv",
                                  "text/comma-separated-values,text/plain",
                                  ".csv")),
             
             # Horizontal line ----
             tags$hr(),
             
             # Input: Checkbox if file has header ----
             checkboxInput("header", "Header", TRUE),
             
             # Input: Select separator ----
             radioButtons("sep", "Separator",
                          choices = c(Comma = ",",
                                      Semicolon = ";",
                                      Tab = ""),
                          selected = ""),
             
             # Input: Select quotes ----
             radioButtons("quote", "Quote",
                          choices = c(None = "",
                                      "Double Quote" = '"',
                                      "Single Quote" = "'"),
                          selected = '"'),
             
             # Input: Select decimal ----
             
             radioButtons("decimal","Decimal",
                          choices = c(Comma = ",",
                                      Dot = "."),
                          selected=","),
             
             # Horizontal line ----
             tags$hr(),
             
             # Main panel for displaying outputs ----
             
             
             # Output: Data file ----
             DT::dataTableOutput("contents")
    ),
    tabPanel("Grouping",
             actionButton("browser", label = ), 
             varSelectInput("selected", "Selected:", data, multiple = TRUE),
             varSelectInput("groupby", "Grouping:", data, multiple=TRUE),
             
             box(
               title="Summary",
               status="warning",
               solidHeader=TRUE,
               verbatimTextOutput("group_summary")
             )
    )
  )
)
)

shinyApp(ui,server)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...