whv20
whv20

Reputation: 241

Produce table with data bars in base R or ggplot2

I am looking to make a table with horizontal bar graphs in each cell to display continuous numeric data with 2 categorical independent variables. It would look similar to the below (fictional data):

A 4 by 4 table with a horizontal bar in each cell. Title is Number of holiday accommodation properties by type and region. Columns denote accommodation type (Hotel, Bed and breakfast, self-catering and campsite). Rows denote region (north, south, east and west).

I have previously tried using formattable, but have had great difficulty saving the output. It seems it is only possible using phantomjs, which I cannot install on my work computer. Alternatively, I can manually copy from the RStudio viewer, but this gives a very pixelated output. It seems there must be a better way

Is there a solution using ggplot2 or base R? This would also make it easier to customise the output than when using formattable.

Upvotes: -2

Views: 80

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174576

I think I would just create this as a faceted ggplot:

library(tidyverse)

holiday_accommodation %>% 
  pivot_longer(-Region, names_to = 'Accommodation type') %>%
  mutate(`Accommodation type` = gsub('_', ' ', `Accommodation type`)) %>%
  mutate(Region = factor(Region, c('West', 'East', 'South', 'North'))) %>%
  mutate(`Accommodation type` = factor(`Accommodation type`,
            c('Hotel', 'Bed and breakfast', 'Self catering', 'Campsite'))) %>%
  mutate(xval = max(value) + 30) %>%
  ggplot(aes(value, Region)) +
  geom_col(fill = '#7399cb', color = 'black') +
  geom_text(aes(x = xval, label = value)) +
  facet_grid(Region ~`Accommodation type`, scales = 'free', switch = 'y') +
  scale_x_continuous("Accommodation type",
                     expand = c(0, 0, 0.2, 2.5), position = 'top') +
  theme_bw(14) +
  theme(axis.ticks = element_blank(),
        axis.text = element_blank(),
        panel.spacing = unit(0, 'mm'),
        strip.background = element_rect(fill = NA),
        strip.text.y.left = element_text(angle = 0),
        panel.grid = element_blank(),
        axis.title = element_text(face = 2))

faceted barplot


Data inferred from table in question

holiday_accommodation <- data.frame(
  Region = c("North", "South", "East", "West"),
  Hotel = c(46, 179, 86, 156),
  Bed_and_breakfast = c(31, 104, 128, 107),
  Self_catering = c(38, 69, 112, 94),
  Campsite = c(23, 95, 74, 98)
)

Upvotes: 2

Related Questions