reorder bars with 'geom_bar(position = "fill",stat = "identity")'

Hi people,

I've made a bar plot, but I was unable to reorder the bars in a meaningful way. I'd like, for instance, to reorder from 100% "Sim" (yes) to 100% "Não" (no).

I've tried to reorder with the values of "Sim", with

mutate(to_reorder = if_else(voto == "Sim", perc, 0),

but it doesn't work.

Here is my code:

df %>%
mutate(to_reorder = if_else(voto == "Sim", perc, 0)) %>%
mutate(partido = fct_reorder(partido, to_reorder)) %>%
arrange(desc(to_reorder)) %>% #pull(partido)
ggplot(aes(y = partido, x = perc, fill = voto))+
geom_bar(position = "fill",stat = "identity")+
geom_text(aes(label=perc), position = position_fill(vjust = 0.5), color = "white")+
theme_minimal()

And the data:

df <- structure(list(partido = c("Avante", "Avante", "Avante", "Cidadania",
"Cidadania", "DEM", "DEM", "DEM", "MDB", "MDB", "MDB", "Novo",
"Novo", "Patriota", "Patriota", "PCdoB", "PDT", "PDT", "PDT",
"PL", "PL", "PL", "Podemos", "Podemos", "Podemos", "PP", "PP",
"PP", "PROS", "PROS", "PROS", "PSB", "PSB", "PSB", "PSC", "PSD",
"PSD", "PSD", "PSDB", "PSDB", "PSDB", "PSL", "PSL", "PSL", "PSOL",
"PSOL", "PT", "PT", "PTB", "PTB", "PTB", "PV", "PV", "Rede",
"Republican", "Republican", "Republican", "S.Part.", "Solidaried",
"Solidaried", "Solidaried"), voto = c("Abstenção/ Não comparecimento",
"Nao", "Sim", "Nao", "Sim", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Abstenção/ Não comparecimento", "Nao", "Sim",
"Nao", "Sim", "Nao", "Sim", "Nao", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Abstenção/ Não comparecimento", "Nao", "Sim",
"Abstenção/ Não comparecimento", "Nao", "Sim", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Abstenção/ Não comparecimento", "Nao", "Sim",
"Abstenção/ Não comparecimento", "Nao", "Sim", "Sim", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Abstenção/ Não comparecimento", "Nao", "Sim",
"Abstenção/ Não comparecimento", "Nao", "Sim", "Abstenção/ Não comparecimento",
"Nao", "Abstenção/ Não comparecimento", "Nao", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Nao", "Sim", "Nao", "Abstenção/ Não comparecimento",
"Nao", "Sim", "Nao", "Abstenção/ Não comparecimento", "Nao",
"Sim"), n = c(2L, 4L, 2L, 5L, 3L, 7L, 8L, 13L, 8L, 10L, 15L,
3L, 5L, 2L, 4L, 8L, 1L, 18L, 6L, 7L, 23L, 11L, 2L, 2L, 6L, 11L,
13L, 16L, 2L, 1L, 8L, 3L, 17L, 11L, 11L, 4L, 11L, 20L, 6L, 12L,
14L, 2L, 6L, 45L, 1L, 8L, 2L, 51L, 2L, 2L, 6L, 2L, 2L, 1L, 3L,
3L, 26L, 1L, 2L, 7L, 5L), perc = c(25, 50, 25, 62, 38, 25, 29,
46, 24, 30, 45, 38, 62, 33, 67, 100, 4, 72, 24, 17, 56, 27, 20,
20, 60, 28, 32, 40, 18, 9, 73, 10, 55, 35, 100, 11, 31, 57, 19,
38, 44, 4, 11, 85, 11, 89, 4, 96, 20, 20, 60, 50, 50, 100, 9,
9, 81, 100, 14, 50, 36)), row.names = c(NA, -61L), class = c("tbl_df",
"tbl", "data.frame"))

Could someone help me? Thanks in advance.

Hey Rony,

I think the reason that fct_reorder isn't working is that you have repeated values in the partido column, which may be causing the reordering to have problems. My general strategy for these types of things would be to define a vector that has the order that I want the values in partido and then use factor(x, levels=order_vector) to set the order before plotting the data. You can see this in my mutate function call in the second code block below.

Your data is a little tricky because some of the values of partido don't have a Sim value in voto. What I did to get it to work was to take df and pivot_wider, replacing the missing values with 0 and then use arrange to order the parties by Sim and Nao. You could do Sim and the other category depending on what you wanted to do

sim <- df %>%
  select(-n) %>%
  pivot_wider(names_from="voto", values_from="perc", values_fill = 0) %>%
  arrange(Sim, Nao)

Then sim$partido would have the parties in the order you want them. So you can do the following to get the plot how you want it

df %>%
  mutate(partido = factor(partido, levels = sim$partido)) %>%
  ggplot(aes(y = partido, x = perc, fill = voto)) +
  geom_bar(position = "fill", stat = "identity") +
  geom_text(aes(label = perc),
            position = position_fill(vjust = 0.5),
            color = "white") +
  theme_minimal()

Pat

1 Like

Uol! Thank you very much Riffomonas!

That was exactly what I wanted. Thanks for explaining in detail what you've done. In addition, I've learned some new features like values_fill = 0 :slight_smile:

Best wishes!!!!!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.