vulpith
vulpith

Reputation: 135

Remove repeated category labels from faceted bar plot created with ggplot2

I am trying to create a faceted bar plot in R using ggplot2. I managed to create the plot, but I cannot figure out how to annotate it correctly. Please, consider the following R code:

library(ggplot2)
library(reshape)
result <- c(0.05, 0.06, 0.08, 0.04, 0.05, 0.09, 1.05, 0.75, 1.4, 1.45)
group <- c("group.1", "group.1", "group.2", "group.1", "group.2", "group.1", "group.1", "group.2", "group.2", "group.2")
char_b <- c("b.1", "b.2", "b.2", "b.2", "b.1", "b.2", "b.2", "b.1", "b.1", "b.1")
char_c <- c("c.1", "c.1", "c.2", "c.2", "c.3", "c.3", "c.4", "c.4", "c.5", "c.5")
char_d <- c("d.1", "d.2", "d.1", "d.1", "d.2", "d.2", "d.1", "d.2", "d.2", "d.2")
approach <- c("method a", "method a", "method a", "method a", "method a", "method b", "method b" , "method b", "method b", "method b")

my_data <- data.frame(result, group, char_b, char_c, char_d, approach, stringsAsFactors=TRUE)
my_data <- melt(my_data, id=c("result","group","approach"))

df_plot <- ggplot(my_data, aes(x=variable, y=result, fill=value)) + 
  geom_bar(stat="identity") + 
  geom_text(aes(label = value), 
            position = position_stack(vjust = 0.5)) +
  facet_wrap(approach ~ group, scales="free_x") +
  theme(
    legend.position="none",
    axis.title.y = element_blank(),
    strip.text.x = element_text(margin = margin(.05, 0, .05, 0, "cm"))
  ) +
  coord_flip()
df_plot

The above code produces the following result:

As you can see, the problem with this figure is that there are repeated labels (e.g., the labels for d.1, c.1, and b.2 appear twice in the plot for method a, group.1). I wonder if it is possible to show only one label for each level of the categories. I assume that this problem arises because I had to reshape the data frame to create the facets; nevertheless, I have not been able to solve it.

Thank you very much for your help.

Best wishes,

Upvotes: 0

Views: 208

Answers (1)

Roman
Roman

Reputation: 17648

You can go for a tidyverse. But the trick is to sum up the data beforehand.

library(tidyverse)
data.frame(result, group, char_b, char_c, char_d, approach, stringsAsFactors=TRUE) %>% 
  pivot_longer(cols = -c("result","group","approach")) %>% 
  group_by(approach, group, name, value) %>% 
  summarise(result = sum(result)) %>% 
  ggplot(aes(name, result, fill = value)) + 
   geom_col(show.legend = F) +
   geom_text(aes(label = value), 
            position = position_stack(vjust = 0.5)) +
   coord_flip() + 
   facet_wrap(approach ~ group, scales="free_x")

enter image description here

In base R you can try

aggregate(result ~ variable + approach + group + value, my_data, sum)

or simply

aggregate(result ~ ., my_data, sum)

Upvotes: 1

Related Questions