0

I would like to plot likert scale data with percentage on the horizontal axis and Items on the vertical axis. I also want to show the percentages in the middle of each bar.

I have tried the following codes, however the graph is totally blank. It only shows the labels of x-axis and y-axis.

Item <- c("EO1_PS", "EO1_OS", "EO2_PS", "EO2_OS")
SA <- c(0, 36, 0, 27)
A <- c(0, 64, 0, 73)
N <- c(0, 0, 0, 0)
D <- c(0, 0, 0, 0)
SD <- c(0, 0, 0, 0)
NAP <- c(100, 0, 100, 0)

# Creating Data Frame

df <- data.frame(Item, SA, A, N, D, SD, NAP)
print(df)

df <- df %>%
  rename(
    "Strongly Agree" = SA,
    "Agree" = A,
    "Neutral" = N,
    "Disagree" = D,
    "Strongly Disagree" = SD,
    "Not Applicable" = NAP
  )

likert <- df %>%
  gather(response, percent, -Item)
likert

ind_order <- likert %>%
  filter(response == "Not Applicable") %>%
  arrange(desc(percent))

lik <- likert %>%
  mutate(Item = factor(Item, levels = ind_order, ordered = TRUE)) %>%
  mutate(response = factor(response,
    levels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable"), ordered = TRUE,
    labels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable")
  )) %>%
  mutate(percent = ifelse(response %in% c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable"), percent))

# Plot

gg <- ggplot()
gg <- gg + geom_hline(yintercept = 0)

gg <- gg + geom_text(
  data = filter(lik, percent > 0),
  aes(x = Item, y = percent, group = response, label = paste(percent * 100, "%")),
  position = "stack", hjust = 1, size = 2.5, color = "white"
)

gg <- gg + scale_x_discrete(expand = c(0, .75))
gg <- gg + scale_fill_manual(
  values = c("#4393c3", "#92c5de", "#b2182b", "gray"),
  drop = FALSE
)
gg <- gg + scale_y_continuous(
  expand = c(0, .10),
  breaks = seq(.35, 1, .25),
  limits = c(.35, .95)
)
gg <- gg + coord_flip()
gg <- gg + theme_bw()
gg <- gg + theme(axis.ticks = element_blank())
gg <- gg + theme(panel.border = element_blank())
gg <- gg + theme(panel.grid.major.y = element_blank())
gg <- gg + theme(panel.grid = element_blank())
gg
stefan
  • 90,330
  • 6
  • 25
  • 51

1 Answers1

0

There are several issues with your code. In general, if something does not work as desired it's always a good strategy to comment out some code lines to figure out what's the issue. In particular, if you get a blank plot then quite often the reason are misspecified limits.

Here is a working example to get you started:

library(tidyverse)

likert <- df %>%
  rename(
    "Strongly Agree" = SA,
    "Agree" = A,
    "Neutral" = N,
    "Disagree" = D,
    "Strongly Disagree" = SD,
    "Not Applicable" = NAP
  ) %>%
  pivot_longer(-Item, names_to = "response", values_to = "percent") %>%
  mutate(
    Item = reorder(Item, ifelse(response == "Not Applicable", -percent, 0), FUN = sum),
    response = factor(response,
      levels = c("Strongly Agree", "Agree", "Neutral", "Disagree", "Strongly Disagree", "Not Applicable")
    )
  )

ggplot(likert, aes(x = percent, y = Item, fill = response)) +
  geom_vline(xintercept = 0) +
  geom_col() +
  geom_text(
    aes(label = ifelse(percent > 0, paste(percent, "%"), "")),
    position = position_stack(vjust = .5), size = 2.5, color = "white"
  ) +
  # scale_fill_manual(
  #   values = c("#4393c3", "#92c5de", "#b2182b", "gray"),
  #   drop = FALSE
  # ) +
  theme_bw() +
  theme(
    axis.ticks = element_blank(),
    panel.border = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid = element_blank()
  )

stefan
  • 90,330
  • 6
  • 25
  • 51