Search code examples
rshinyreshapeshiny-servermelt

DT::dataTableOutput with table in long form and still having full functionality?


In R Shiny, I have a data table in wide form, let's all this Representation A of the data:

Rank Person School
1 Sean Boston
2 Alicia

I'm using DT::dataTableOutput to present this table. I want to instead present this table in long form (Rank identifies the observations):

Rank Variable Value of Variable
1 Person Sean
1 School Boston
2 Person Alicia
2 School

I will then also style this table slightly differently, I will:

  • Only print the first occurrence of a value of rank

The table then becomes:

Rank Variable Value of Variable
1 Person Sean
School Boston
2 Person Alicia
School

I will also:

  • Drop empty rows

So the final table, which we will call Representation B of the data, becomes:

Rank Variable Value of Variable
1 Person Sean
School Boston
2 Person Alicia

When presenting the table in the format B, I still want to keep as much of the functionality as possible that DT::dataTableOutput supplies for form A, e.g. the ability to search and sort (without separating rows belonging together) etc. Here, by sorting I don't mean the order variables are presented in within a given rank, but the order the "rank groups" are presented. For example, sorting on Person should yield the following since Alicia comes before Sean lexicographically:

Rank Variable Value of Variable
2 Person Alicia
1 Person Sean
School Boston

What do you think is the easiest way to implement this?

Currently, I consider two different ways. In both plans, instead of having the standard sorting buttons provided by DT::dataTableOutput, I will link e.g. a radio button which will allow the user to choose which variable the table should be sorted on (i.e. Rank, Person, or School).

My first option for implementation: When the radio button is pressed, I will (without the user seeing it) transform the table to representation A, sort it there, then transform it to the properly sorted version of representation B.

My second option for implementation: I could to representation B "attach" representation A (without showing the latter to the user) so that each row of the underlying data contains the full information for that rank:

Rank Variable Value of Variable Rank_Long Person_Long School_Long
1 Person Sean 1 Sean Boston
School Boston 1 Sean Boston
2 Person Alicia 2 Alicia

If I want to obtain the lexicographically sorted B representation, I order the table above by (Person_Long, Rank_Long, Variable). The extra Variable in the ordering is added to get the rows presented to the user (Rank and Variable) in the right order (Person above School).

In practice, I will have around five to ten variables rather than only two (and each of these ten should be allowed to sort on), and I will be running Shiny Server on an AWS server which will be reached through an iframe on a website.

Pros and cons of the first and second options for implementation:

  1. First option: Fast if the dcast and melt functions are fast enough and if melt can be set to preserve the sorting when transforming to long. Should provide faster initial load time of the table for the user since the table won't have as many columns as the second option.
  2. Second option: No reshape needed, but more data sent to the user at initial load.

Which of my two options do you think is the best, and do you have suggestions about other implementations I haven't considered?


Solution

  • I concatenated my columns of interest using paste with properly placed <br> tags for line break. Using DT::datatable(..., escape = FALSE) I could then obtain the table in the form I wanted.

    I defined a sliderInput (outside of the table) whose input I set to trigger events for sorting. The table reloads (thus resetting search) when the slider obtains a new input, I will try to fix that (with some filter or proxy solution, or hopefully I find a simple way).