Home > Back-end >  R Shiny : Get data from selected row
R Shiny : Get data from selected row

Time:11-08

I want to extract data from a table for use in a calculation.

My starting point is https://shiny.rstudio.com/gallery/basic-datatable.html

Essentially I want be able to select a row (say row 8) and from that get model = "a4 quattro" and trans = "manual(m5)".

I've looked for examples but can't see how to apply this. It seems very complex for what (in my view) should be simple.

This is my first day on my first R-shiny application and I'm definitely lost.

Can someone help?

CodePudding user response:

Here is a complete example based on the Shiny example you referenced. This uses mpg data from ggplot2.

First, you can create a reactive expression to determine which rows should be filtered and shown in the table. Whenever one of your inputs change, then the reactive expression will be reevaluated. To access the filtered data, you can reference as filtered_rows() (note the parentheses).

To get the selected rows, you can use input$table_rows_selected since your dataTableOutput is called table (just append "_rows_selected"). This can be one or more than one rows, and returns row numbers (e.g., 8 in your example above). Then, to extract your data, you can use filtered_rows()[input$table_rows_selected, c("model", "trans")] which will include model and trans column data for the filtered rows.

The verbatimTextOutput and toString simply show the results for validation and demonstration. You can use the results in another context as well.

library(shiny)
library(DT)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Basic DataTable"),
  
  # Create a new Row in the UI for selectInputs
  fluidRow(
    column(4,
           selectInput("man",
                       "Manufacturer:",
                       c("All",
                         unique(as.character(mpg$manufacturer))))
    ),
    column(4,
           selectInput("trans",
                       "Transmission:",
                       c("All",
                         unique(as.character(mpg$trans))))
    ),
    column(4,
           selectInput("cyl",
                       "Cylinders:",
                       c("All",
                         unique(as.character(mpg$cyl))))
    )
  ),
  # Create a new row for the table.
  DT::dataTableOutput("table"),
  verbatimTextOutput("text")
)

server <- function(input, output) {
  
  # Filter data based on selections
  filtered_rows <- reactive({
    data <- mpg
    if (input$man != "All") {
      data <- data[data$manufacturer == input$man,]
    }
    if (input$cyl != "All") {
      data <- data[data$cyl == input$cyl,]
    }
    if (input$trans != "All") {
      data <- data[data$trans == input$trans,]
    }
    data
  })
  
  # Show filtered data in the datatable
  output$table <- DT::renderDataTable(DT::datatable({ filtered_rows() }))
  
  # Show selected text
  output$text <- renderText({ toString(filtered_rows()[input$table_rows_selected, c("model", "trans")]) })
  
}

shinyApp(ui, server)
  • Related