Search code examples
rshinyreactable

How to merge some table cells in Reactable


I'm trying to create a reactable that will display statistics for a large number of categorical variables. The table should show the following columns: variable name, categories of variable, categories frequency, percentage, number of valid, and number of missing values.I would like to merge some table cells so that the values are not duplicated. I would like to merge: variable name, Valid Count and Missing Count. I could do this with java script, but I don't know that language.

This is the code I'm working on:

library(dplyr)
library(reachable)



calculate_summary <- function(x) {
  data_summary <- data.frame(Category = x) %>%
    count(Category, name = "Frequency") %>%
    mutate(Percent = (Frequency / sum(Frequency)) * 100,
           Valid_Count = sum(!is.na(Category)),
           Missing_Count = sum(is.na(Category))) %>%
    select(Category, Frequency, Percent, Valid_Count, Missing_Count)
  
  return(data_summary)
}



# Function to create the reactable
create_reactable <- function(data) {
  data_summary <- lapply(data, calculate_summary)
  combined_data <- do.call(rbind, data_summary)
  reactable(
    combined_data,striped = TRUE, resizable = TRUE, wrap = FALSE,
    style = list(
      fontFamily = "Helvetica"),
    
    columns = list(
      Category = colDef(name = "Category"),
      Frequency = colDef(name = "Count"),
      Percent = colDef(name = "Percent %"),
      Valid_Count = colDef(name = "Valid Count"),
      Missing_Count = colDef(name = "Missing Count")
    ),
    showPagination = TRUE
  )
}

# Example data
set.seed(123)
data <- data.frame(
  Variable = c("A", "B", "C", "D", "E", NA),
  Proba = c("A", "B", "C", "D", "E", NA)
  )
  


# Create the reactable using the function
reactable_data <- create_reactable(data)

# Display the reactable
reactable_data

With that code I get the following table design:

enter image description here

However, I would like to merge some cells.The table would look like this.

enter image description here

thanks!


Solution

  • Here is one possibility.

    enter image description here

    You could get this by using:

    library(dplyr)
    library(reactable)
    
    calculate_summary <- function(x) {
        data_summary <- data.frame(Category = x) %>%
            count(Category, name = "Frequency") %>%
            mutate(Percent = (Frequency / sum(Frequency)) * 100,
                   Valid_Count = ifelse(Category == "C", sum(!is.na(Category)), NA),
                   Missing_Count = ifelse(Category == "C", sum(is.na(Category)), NA)) %>%
            select(Category, Frequency, Percent, Valid_Count, Missing_Count) 
        
        return(data_summary)
    }
    
    # Function to create the reactable
    create_reactable <- function(data) {
        data_summary <- lapply(data, calculate_summary)
        combined_data <- do.call(rbind, data_summary) |> 
            tibble::rownames_to_column("Name") |> 
            mutate(Name = ifelse(Category != "C", "", Name)) |> 
            mutate(Name = gsub("\\..*","",Name)) 
        
        reactable(
            combined_data,striped = TRUE, resizable = TRUE, wrap = FALSE,
            style = list(
                fontFamily = "Helvetica"),
            
            columns = list(
                Category = colDef(name = "Category"),
                Frequency = colDef(name = "Count"),
                Percent = colDef(name = "Percent %"),
                Valid_Count = colDef(name = "Valid Count"),
                Missing_Count = colDef(name = "Missing Count")
            ),
            showPagination = TRUE
        )
    }
    
    # Example data
    set.seed(123)
    data <- data.frame(
        Variable = c("A", "B", "C", "D", "E", NA),
        Proba = c("A", "B", "C", "D", "E", NA)
    )
    
    # Create the reactable using the function
    reactable_data <- create_reactable(data)
    
    # Display the reactable
    reactable_data