0

I am a beginner with R, and I have to analyze the results of a survey including Likert scales. I would like to have multiple stacked histograms to visually compare the answers to multiple Likert questions. After no succeeding with ggplot only, I tried to use the likert package which seem to work fine (except that it does not use the columns labels), but I would like to adjust the white margin on the sides of the plot.

Here is an example (coming from here):

library(likert)
data(pisaitems)

items24 <- pisaitems[,substr(names(pisaitems), 1,5) == 'ST24Q']

items24 <- rename(items24, c(
            ST24Q01="I read only if I have to.",
            ST24Q02="Reading is one of my favorite hobbies.",
            ST24Q03="I like talking about books with other people.",
            ST24Q04="I find it hard to finish books.",
            ST24Q05="I feel happy if I receive a book as a present.",
            ST24Q06="For me, reading is a waste of time.",
            ST24Q07="I enjoy going to a bookstore or a library.",
            ST24Q08="I read only to get information that I need.",
            ST24Q09="I cannot sit still and read for more than a few minutes.",
            ST24Q10="I like to express my opinions about books I have read.",
            ST24Q11="I like to exchange books with my friends."))

l24g <- likert(items24[,1:2], grouping=pisaitems$CNT)
plot(l24g)

Result of the example above.

There are large white margins on both sides of the plot that I would like to reduce (or completely remove when I disable low or high percentages). To be explicit, it's not about the edges of the image, but the white spaces between the grey frame and the actual histogram (where there are the percentages). Also the percents on the left side seem to be "bonded" to the plot, which is not very aesthetic.

It would be perfect if I could get a rendering close to this one.

Example of the desired result.

So, how can I adjust the position of the high/low percents and/or of the white margins to save some place for the histograms?

PS: I apologize for my english mistakes...

Michael Marx
  • 104
  • 8

1 Answers1

0

If you want this kind of plot, you really don't need the likert package at all. Just pivot into long format, summarize the data and draw it as a bar graph:

library(tidyverse)

pivot_longer(items24, everything()) %>%
 group_by(name) %>%
  count(value) %>%
  filter(!is.na(value)) %>%
  mutate(percentage = n/sum(n)) %>%
  ggplot(aes(percentage, name, fill = value)) +
  geom_col(position = position_stack(reverse = TRUE)) +
  geom_text(aes(label = scales::percent(percentage, 1), group = value),
            position = position_fill(vjust = 0.5, reverse = TRUE),
            color = 'white', fontface = 2) +
  scale_fill_manual(values = c('navy', 'deepskyblue4', 
                               'deepskyblue2', 'lightblue')) +
  theme_bw() +
  coord_cartesian(expand = FALSE) +
  scale_x_continuous(labels = scales::percent) +
  labs(fill = NULL, x = NULL, y = NULL) +
  theme(legend.position = 'bottom')

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Oh it's really beautiful! However on my side the computed percentages are about x10 times too small, and weirdly enough they don't sum to 100 (for instance the sum of percentages for ST24Q01 equals 0.0208+0.0327+0.0278+0.00976 = 0.09106). – Michael Marx Feb 23 '23 at 16:06
  • In that case @MichaelMarx change `position_stack(reverse = TRUE)` to `position_fill(reverse = TRUE)` inside `geom_col` – Allan Cameron Feb 23 '23 at 16:24
  • Yeah it works! But then the displayed percentages are absurdly small. In fact I think they're percentages of a value across the whole plot (and not for each line). – Michael Marx Feb 23 '23 at 17:05
  • @MichaelMarx my code above works with the sample data you have provided. There must be something different about your own data that is causing this issue. Perhaps you can edit your question to include your real data in reproducible format? – Allan Cameron Feb 23 '23 at 17:26
  • My bad, I think there was a conflict on my side or something, because it mysteriously solved itself (sorry). Thank you so much! – Michael Marx Feb 25 '23 at 13:58