Create a Top N Rank to filter a Data table in Shiny

shiny
shinydashboard

#1

Hi,

I hope you can help me out on this request.

I’m working on a Shiny dashboard where I’d like to create a Top N Rank filter I can apply to a data table.

What’s the best way to apply it? Should I create a reactive function in the server or is there any best way?

The objective is to type the number I want to filter the table. Ex: Top 10, 20…

I’m sending a simplified version of the code.

Thank you very much in advance for your time and help. Much appreciated.

Juanma

UI

> ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      box(DT::dataTableOutput("table1"), width=10, height=600))
  )
)

Server

> server <- function(input, output) {
  output$table1 <- renderDataTable({
    datatable(dataset_DB)
  })  
 }

shinyApp(ui, server)


#2

All you need to do for this example is put the filter code inside the `renderDataTable({}) function. So something like:

server <- function(input, output) {
  output$table1 <- renderDataTable({
    datatable(dataset_DB[1: input$n_rank, ])
  })  
 }

Where input$n_rank is where the user selects the number of rows they want to see. However if your app gets more complicated then you’ll want to create a reactive dataset using reactive to handle the filtering like this:

server <- function(input, output) {

   filt_df <- reactive(dataset_DB[1: input$n_rank, ])
  output$table1 <- renderDataTable({
    datatable(filt_df())
  }) 
 }

That way you can call filt_df() to generate the reactive dataset wherever you use it, for instance if you wanted to include a plot. The reason to pull things out into reactive is that it will help reduce code re-use and protect you from accidentally filtering the dataset too many times if the dataset is rendered frequently.


#3

Hi @gordon

Thank you so much for your reply. I very much appreciate it. It’s great.

I will follow your second recommendation. It works perfectly.

In the case I had different columns in my data table and wanted to select the column I want to rank by.

How should I modify your second reactive argument? Could I pass the input$variable from the UI below within the reactive function you suggested?

box(selectInput("Variable", "Please Select Variable to rank", 
                      choices = colnames)) 

Thanks


#4

Yup! Although I think the datatables output allows people to sort by different columns if that’s what you’re after.


#5

yes, I’d like to sort by different columns.


#6

Hi,

I’m trying to run the following code with the objective of ranking by datatable with the column select under the “SelectInput” created. However, I don’t think I’m passing it to server properly as I continue to get the error

x must be a data.frame or data.table.

This is the code I’m running

Ui

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      box(DT::dataTableOutput("table1"), width=10, height=600),
      box(textInput(inputId = "n_rank",
                    label = "Choose a number",
                    value = 25)),
      box(selectInput("variable", "Please Select Variable to rank", 
                      choices = colnames))            
    )
  )
)

Server

server <- function(input, output) {
   filt_df <- reactive(dataset_DB2[1: input$n_rank, ][setorder(input$variable)])
   output$table1 <- renderDataTable({
    datatable(filt_df()) 
      }) 
 }

shinyApp(ui, server)

Hope you can help me out. Much appreciated.

Juanma