rggplot2formattable

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.


Solution

  • 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)
    )