I have 2 numerical (sales; cost) and 2 categorical (model; level) variables:
model level sale cost Colour
1 A HIGH 100 -110 black
2 B HIGH 120 -89 khaki1
3 C HIGH 500 -20 red
4 D HIGH 455 -300 green
5 E HIGH 456 -110 chocolate
6 F HIGH 12 -120 orange
7 G HIGH 56 -56 blue
8 H HIGH 98 -300 gold
9 All HIGH 889 -790 sienna
10 Z HIGH 456 -30 yellow
11 A LOW 432 -70 black
12 B LOW 567 -40 khaki1
13 C LOW 345 -30 red
14 D LOW 345 -120 green
15 E LOW 100 -10 chocolate
16 F LOW 67 -21 orange
17 G LOW 34 -24 blue
18 H LOW 110 -540 gold
19 All LOW 670 -123 sienna
20 Z LOW 160 -45 yellow
Next I built barchart with negative and positive bars, which is split into 2 part according to level column and ranked from TOP to Down by sales
ggplot()
geom_col(aes(value, tidytext::reorder_within(model, value, level),
fill = model, color = model),
data = df[df$sign == "sale", ],
position = "stack")
scale_fill_manual(values = Colour, breaks = df$model)
scale_color_manual(values = Colour, breaks = df$model)
geom_col(aes(value, tidytext::reorder_within(model, value, level),
color = model),
data = df[df$sign == "cost", ],
fill = "white",
position = "stack")
tidytext::scale_y_reordered()
labs(fill = "model")
facet_grid(level ~ ., switch = "y",scales = "free_y")
theme(axis.text.x = element_text(angle = 90),
strip.background = element_rect(fill = "white"),
strip.placement = "outside",
strip.text.y.left = element_text(angle = 0),
panel.spacing = unit(0, "lines"))
theme(legend.position="none")
labs(y = " ") geom_vline(xintercept = 0,linetype="dotted", color="white")
Now I want to set Z row always in the end on the plot and All always on the TOP:
CodePudding user response:
One option to achieve your desired result would be to add a helper value column to your data where you assign a value of e.g. -Inf
to Z
and which is used to set the order of the categories. This way Z
will be put at the last position.
Note: I removed scale_color/fill_manual
as you haven't provided your colors.
library(ggplot2)
df <- df |>
tidyr::pivot_longer(c(sale, cost), names_to = "sign") |>
dplyr::mutate(value1 = ifelse(model == "Z", -Inf, value))
ggplot()
geom_col(aes(value, tidytext::reorder_within(model, value1, level),
fill = model, color = model),
data = df[df$sign == "sale", ],
position = "stack")
geom_col(aes(value, tidytext::reorder_within(model, value1, level),
color = model),
data = df[df$sign == "cost", ],
fill = "white",
position = "stack")
tidytext::scale_y_reordered()
labs(fill = "model")
facet_grid(level ~ ., switch = "y",scales = "free_y")
theme(axis.text.x = element_text(angle = 90),
strip.background = element_rect(fill = "white"),
strip.placement = "outside",
strip.text.y.left = element_text(angle = 0),
panel.spacing = unit(0, "lines"))
theme(legend.position="none")
labs(y = " ") geom_vline(xintercept = 0,linetype="dotted", color="white")
DATA
structure(list(model = c("A", "B", "C", "D", "E", "F", "G", "H",
"All", "Z", "A", "B", "C", "D", "E", "F", "G", "H", "All", "Z"
), level = c("HIGH", "HIGH", "HIGH", "HIGH", "HIGH", "HIGH",
"HIGH", "HIGH", "HIGH", "HIGH", "LOW", "LOW", "LOW", "LOW", "LOW",
"LOW", "LOW", "LOW", "LOW", "LOW"), sale = c(100L, 120L, 500L,
455L, 456L, 12L, 56L, 98L, 889L, 456L, 432L, 567L, 345L, 345L,
100L, 67L, 34L, 110L, 670L, 160L), cost = c(-110L, -89L, -20L,
-300L, -110L, -120L, -56L, -300L, -790L, -30L, -70L, -40L, -30L,
-120L, -10L, -21L, -24L, -540L, -123L, -45L), Colour = c("black",
"khaki1", "red", "green", "chocolate", "orange", "blue", "gold",
"sienna", "yellow", "black", "khaki1", "red", "green", "chocolate",
"orange", "blue", "gold", "sienna", "yellow")), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19", "20"))