Why am I losing the grouping column header in renderDT when renaming the other columns in the table?

0

Issue

When running the below MWE code exactly as drafted, you’ll see how in the bottom table titled "Sum the data table columns:", the left-most column header, the grouping key, changes as the user selects how to group the data by (by either Period_1 or by Period_2).

But I’d like to change the names of the remaining column headers, "ColA" and "ColB", to "Col A" and "Col B" for example. (This is because in the fuller App this example is deployed I’m trying to use more industry-standard descriptions for the columns and need the white spaces — bear with me here). To change these 2 column headers, I use the colnames = (...) function under renderDT(...) in the server section. Note how this line is commented-out below. Now uncomment it, run the code, and see how the name for the left-most column, the grouping key, is dropped. I’d like to retain the grouping column header name ("Period_1" or "Period_2" depending on user input).

Any ideas how to retain it?

Here’s the MWE code:

library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
library(tidyverse)


ui <-
  fluidPage(
    fluidRow(
      column(width = 8,
          h3("Data table:"),
          tableOutput("data"),
          h3("Sum the data table columns:"),
          radioButtons(
            inputId = "grouping",
            label = NULL,
            choiceNames = c("By period 1", "By period 2"),
            choiceValues = c("Period_1", "Period_2"),
            selected = "Period_1",
            inline = TRUE
          ),
          DT::dataTableOutput("sums")
      )
    )
  )

server <- function(input, output, session) {
  data <- reactive({
    data.frame(
      Period_1 = c("2020-01", "2020-02", "2020-03", "2020-01", "2020-02", "2020-03"),
      Period_2 = c(1, 2, 3, 3, 1, 2),
      ColA = c(1000.01, 20, 30, 40, 50, 60),
      ColB = c(15.06, 25, 35, 45, 55, 65)
    )
  })
  
  summed_data <- reactive({
    data() %>%
      group_by(!!sym(input$grouping)) %>%
      select("ColA","ColB") %>%
      summarise(across(everything(), sum))
  })
  
  output$data <- renderTable(data())

  output$sums <- renderDT({
    summed_data() %>% 
      datatable(
        rownames = FALSE,
        # colnames = c("Col A","Col B")
        )
  })
  
}

shinyApp(ui, server)

Solution

Implementation of Limey’s solution (only the server section is shown below, everything else remains as shown in OP):

server <- function(input, output, session) {
  data <- reactive({
    data.frame(
      Period_1 = c("2020-01", "2020-02", "2020-03", "2020-01", "2020-02", "2020-03"),
      Period_2 = c(1, 2, 3, 3, 1, 2),
      ColA = c(1000.01, 20, 30, 40, 50, 60),
      ColB = c(15.06, 25, 35, 45, 55, 65)
    )
  })
  
  # add the below to leave grouping column header untouched:
  colNames <- reactive({c(input$grouping, "Col A", "Col B") })
  
  # add the below to replace the "_" in the grouping column header with a blank space:
  # colNames <- reactive({c(stringr::str_replace(input$grouping, fixed("_"), " "), "Col A", "Col B") })
  
  summed_data <- reactive({
    data() %>%
      group_by(!!sym(input$grouping)) %>%
      select("ColA","ColB") %>%
      summarise(across(everything(), sum))
  })
  
  output$data <- renderTable(data())

  output$sums <- renderDT({
    summed_data() %>% 
      datatable(
        rownames = FALSE,
        colnames=colNames() # < add colNames()
        )
  })
  
}

shinyApp(ui, server)

Answered By – Curious Jorge – user9788072

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More