s_o_c_account
s_o_c_account

Reputation: 111

How can I stack labels vertically above ggplot2 bar graph?

I have generated a bar graph with labels on top of the bars and above the standard error bars. However, I would like to rotate the labels so that they stack vertically instead of horizontally. How can I do this?

Here is the data to make the example reproducible:

example <- data.frame(var = c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3),
                      resp = c(1,2,3,4,5,6,7,8,2,4,5,10,3,3,2,9,8,7,6,5,4,3,2,3))

Here is what I have tried:

library(dplyr)
library(ggplot2)

# Convert to factor
example$var <- as.factor(example$var)

# Group by variable means
example_mean <- example %>% 
  group_by(var) %>% 
  summarise(mean = mean(resp), .groups = 'drop')

# Add mean separation labels
example_mean$mean_sep <- c("aasdf","dfdsa","adfdsa")

# Function for standard error of the mean
sem <- function(x) sd(x)/sqrt(length(x))

# Aggregate standard error over variables
example_sem <- example %>% 
  group_by(var) %>% 
  summarise(sem = sem(resp), .groups = 'drop')

# Generate bar graph
ggplot(example_mean, aes(x = var, y = mean))+
  geom_bar(stat="identity", width = 0.4, position = "dodge", col = "black", fill = "maroon")+
  geom_errorbar(aes(ymin = mean, ymax = mean + example_sem$sem), width = 0.2, position = position_dodge(0.6))+
  xlab("var")+ylab("response")+
  theme(plot.title=element_text(hjust=0.5, size = 20),
        axis.text = element_text(size = 15),
        axis.title = element_text(size = 15))+
  ggtitle("Custom Title")+
  geom_text(aes(label=mean_sep, y=mean + example_sem$sem), vjust = -0.9, size = 6) +
  ylim(0, 8)

The following graph is produced: enter image description here

I need to rotate the labels so that they appear vertically stacked, such as this:

enter image description here

How can I do this?

Upvotes: 1

Views: 150

Answers (1)

harre
harre

Reputation: 7297

You could insert a new line between each character. It could for instance be done using purrr. I.e.

geom_text(aes(label  = purrr::map(strsplit(mean_sep, ""),
                                  ~ paste(., collapse = "\n")),
              y      = mean + example_sem$sem
              ),
          vjust      = -0.1,
          lineheight = 0.7,
          size       = 6)

You might want to adjust the lineheight+vjust as well as ylim..

Without purrr: sapply(strsplit(mean_sep, ""), \(x) paste(x, collapse = "\n"))

Output:

enter image description here

Upvotes: 2

Related Questions