micsky
micsky

Reputation: 121

How to re-order datatable column names in a R-Shiny App?

I am writing an App which displays data via datatable. Therefore different forms of text files from users are read in. It is often the case that the order of the columns is mixed up in this files, but the information in it is valid. After displaying the data I want to do some plausibility routines and therefore I want to say: do XY with the data in "Column A". But if there is the wrong data (because of the wrong order of the columns) the plausibility is useless. Therefore I would like reorder the column names like: Column no. 3 is not 'Column A' but contains the data of 'column B', etc.

What I want to do now is to reorder the column names, not the entire column as done here. With the following code I am able to move the whole column, but how do I only move the column names?

Edit: Just to make things clear: no, I don't want to sort the columns while reading in the data. I want to read in the file as it is and just work with the datatable object. This is mainly because I don't know what kind of file i get and what kind of information is in there. So I first of all want to display what's in there and then have a closer look.

library(shiny)
library(DT)

ui <- fluidPage(
      DTOutput("table")
      )

server <- function(input, output, session){
  
    output$table <- renderDT({
    datatable(
      iris,
      rownames = FALSE,
      extensions = "ColReorder",
      options = list(
        colReorder = TRUE
      ),
     colnames = c("S-Length", "S-Width", "P-Length", "P-Width", "Species")
      )
  })
}
 
shinyApp(ui, server)

Upvotes: 2

Views: 1720

Answers (2)

micsky
micsky

Reputation: 121

Well, I guess I found a solution myself via the package shinyjqui.

library(shiny)
library(DT)
library(shinyjqui) # of course you need to install the package first, if you've never used it before

ui <- fluidPage(
  shinyjqui::orderInput("order",
                        "some order",
                        items = c("S-Length", "S-Width", "P-Length", "P-Width", "Species")),
  tags$br(),
  DTOutput("table")
)

server <- function(input, output, session){
 
  output$table <- renderDT({
    
    names(iris) <- input$order
    
    datatable(
      iris,
      rownames = FALSE,
      extensions = "ColReorder",
      options = list(
        colReorder = TRUE
      )
    )
  })
}

shinyApp(ui, server)

Note: With names(iris) <- input$order I've directly changed the columns' names of the data set and not just the names of the datatable, because I wanted to further access the columns by its (new) names. One could also "only" change the (displayed) names for the datatable.

Edit: btw, here is Stéphane Laurent's version (see answer above) modularized, in case anyone needs it.

library(shiny)
library(shinyjqui)
library(DT)#

ui_modul <- function(id) {
  ns <- NS(id)
  tagList(
    jqui_sortable( DTOutput(ns("dtable")), options = list(items= "thead th"))
  )
}

server_modul <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      output[["dtable"]] <- renderDT({
        datatable(head(iris, 5))
      })      
    }
  )
}

ui <- fluidPage(
  br(),
  ui_modul("test")
)

server <- function(input, output, session){
  server_modul("test")
}

shinyApp(ui, server)

Upvotes: 1

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84719

Your solution works but the datatable is re-rendered each time you reorder the column names.

Here is a solution using shinyjqui::jqui_sortable with which the datatable is not re-rendered when one sorts the column names:

library(shiny)
library(shinyjqui)
library(DT)


ui <- fluidPage(
  br(),
  DTOutput("dtable")
)

server <- function(input, output, session){
  
  output[["dtable"]] <- renderDT({
    datatable(head(iris, 5))
  })
  
  jqui_sortable("#dtable thead tr")
  
}

shinyApp(ui, server)

enter image description here

Upvotes: 1

Related Questions