Ploting multidimensions survey responses using gglikert

60 views Asked by At

Consider a data.frame from a resulting survey.

Question <- c("D1-Q1", "D1-Q2", "D1-Q3", "D1-Q4", "D1-Q5", "D1-Q6", "D2-Q1", "D2-Q2", "D2-Q3", "D2-Q4", "D2-Q5", "D2-Q6", "D3-Q1", "D3-Q2", "D3-Q3", "D3-Q4", "D3-Q5", "D3-Q6")
strong_agree <- c(23,NA,4,23,5, 7, 3, 12, 4, 7, 8, 11,5, 7, 22, 6, 3, 7)
agree <- c(23,42,4,23,5, 7, 23, 12, 4, 7, 8, 11,5, 7, 24, 6, 8, 7)
neutral <- c(3,34,4,23,5, 2, 3, 6, 4, NA, 8, 11,5, 7, 2, 3, 3, 7)
disagree <- c(21,12,4,23,5, 4, 2, 16, NA, 7, 8, 11,5, 7, 6, 6, 34, 7)
strong_disagree <- c(44,NA,4,23,5, 7, 2, 17, 4, 7, 8, 11,5, 7, 23, 6, 3, 7)
Dimension <- c("D1", "D1", "D1", "D1", "D1", "D1",  "D2", "D2", "D2", "D2", "D2", "D2", "D3", "D3", "D3", "D3", "D3", "D3")
Region <- c("R1", "R1", "R2", "R2", "R3", "R3", "R1", "R1", "R2", "R2", "R3", "R3", "R1", "R1", "R2", "R2", "R3", "R3")

df <- data.frame(Question, strong_agree, agree,neutral, disagree , strong_disagree, Dimension, Region)

gglikert(df)

Using gglikert, from ggstats package how should the data be prepared in order to create a plot faceting or grouping (?) the Region and Dimension variables like in the image

Survey results, by region

I just can get around on how to use the gglikert to display the results, but it feel so easy.. I feel dumb.

Thank you.

1

There are 1 answers

2
stefan On

Well, I think using gglikert is a bit over the top to create a simple stacked barchart which does not require more than reshaping your data to long and some vanilla ggplot2:

library(ggplot2)
library(tidyr)

df |> 
  tidyr::pivot_longer(-c(Question, Dimension, Region), names_to = "label", values_to = "count") |> 
  ggplot(aes(count, Question, fill = label)) +
  geom_col(position = "fill") +
  scale_x_continuous(labels = scales::label_percent()) +
  scale_fill_brewer(type = "div", palette = "RdYlGn") +
  facet_wrap(~Region) +
  theme_bw()
#> Warning: Removed 4 rows containing missing values (`position_stack()`).

And if you want to present your data as a likert chart you could easily do so by switching to ggstats::position_likert where I also have set NAs to zero and used ggstats::label_percent_abs() for the axis labels:

df |> 
  tidyr::pivot_longer(-c(Question, Dimension, Region), names_to = "label", values_to = "count") |> 
  tidyr::replace_na(list(count = 0)) |> 
  ggplot(aes(count, Question, fill = label)) +
  geom_col(position = ggstats::position_likert()) +
  scale_x_continuous(labels = ggstats::label_percent_abs()) +
  scale_fill_brewer(type = "div", palette = "RdYlGn") +
  facet_wrap(~Region) +
  theme_bw()

enter image description here

And as a reference, here is the way to do it with gglikert:

library(ggplot2)
library(ggstats)
library(tidyr)
library(dplyr, warn=FALSE)

df |> 
  pivot_longer(-c(Question, Dimension, Region), names_to = "label", values_to = "count") |> 
  replace_na(list(count = 0)) |> 
  uncount(count) |> 
  select(-Dimension) |> 
  mutate(id = row_number(), .by = Question) |> 
  pivot_wider(names_from = Question, values_from = label) |> 
  gglikert(include = -c(Region, id), facet_cols = vars(Region))
#> Warning: Removed 108 rows containing missing values (`geom_text()`).