Is there a function that can represent a range of data (with a min and max value) in a horizontal bar within a table?

82 views Asked by At

First question on stack overflow. I'm using R in RStudio to make a table containing some data that I have already formatted in a data frame, some of which contain a low bound and a high bound, for example minimum fertilizer applied (kg/ha) and maximum fertilizer applied (kg/ha) in the same experiment. In some experiments the range is from 0-150, some it is from 200-300, and some the only value is 64. In the attached picture I drew out the type of table bars I am looking for. I don't need an interactive table also. visualisation of what I am looking for

Does anyone know if there is a package in R that can help me make this table? I see R packages like formattable and gt/gtExtras and reactable/reactablefmtr that have functions to make horizontal bars in each table row that represent a single data point, but I haven't seen examples that align with what I'm trying to do.

Thank you in advance for any help or pointers in the right direction!

1

There are 1 answers

0
Allan Cameron On

You can make a stacked bar plot with an invisible lower bar. Suppose your data is like this:

df <- data.frame(Study = paste("Study", 1:7),
                 Low = c(0, 64, 0, 200, 152, 0, 180),
                 High = c(218, 64, 180, 352, 152, 84, 400))

df
#>     Study Low High
#> 1 Study 1   0  218
#> 2 Study 2  64   64
#> 3 Study 3   0  180
#> 4 Study 4 200  352
#> 5 Study 5 152  152
#> 6 Study 6   0   84
#> 7 Study 7 180  400

Then you can do:

library(tidyverse)

df %>%
  mutate(High = High - Low,
         Study = fct_rev(Study)) %>%
  pivot_longer(Low:High) %>%
  ggplot(aes(value, Study, fill = name, color = name)) +
  geom_hline(yintercept = 1:6 + 0.5, col = "lightblue", alpha = 0.3, size = 2) +
  coord_cartesian(expand = FALSE) +
  scale_x_continuous(limits = c(0, 500), position = "top",
                     name = "Fertilizer Application Rate (Kg / ha)") +
  scale_y_discrete(name = NULL) +
  geom_col(size = 2, width = 0.95) +
  geom_text(data = df, inherit.aes = FALSE, size = 6, hjust = 0,
            aes(x = 420, y = Study,
            label = ifelse(Low == High, Low, paste(Low, High, sep = " - ")))) +
  scale_fill_manual(values = c( "#3634bd", "#00000000"), breaks = "High",
                    na.value = "#00000000", guide = "none") +
  scale_color_manual(values = c( "#3634bd", "#00000000"), breaks = "High",
                     na.value = "#00000000", guide = "none") +
  theme_classic(base_size = 20) +
  theme(panel.border = element_rect(fill = NA, linewidth = 1.5),
        plot.margin = margin(30, 30, 30, 30),
        axis.title.x.top = element_text(margin = margin(0, 0, 30, 00)))

enter image description here

Created on 2022-11-19 with reprex v2.0.2