I have the data frame below, called 'subdata.frame'. It's a data from a rent bike company. There are users called 'member' who paid an annual subscription, and the casual riders. Further, we have three types of bikes. The 'n' counts the total of rides in a certain period.
member_casual | rideable_type | n |
---|---|---|
casual | classic_bike | 68941 |
casual | docked_bike | 14503 |
casual | electric_bike | 20990 |
member | classic_bike | 75455 |
member | electric_bike | 17008 |
So, I'm trying to create two donut charts to show the proportion of each type of bike used within the member and casual groups. I'm using the 'facet_grid' (~member_casual) function. But first, it's necessary to create new columns for the percentage and cumulative sums.
subdata.frame <- data.frame(subdata) %>%
group_by(member_casual) %>%
count(rideable_type) %>%
mutate(prop = n/sum(n)) %>%
mutate(ymax = cumsum(prop))
Resulting in the next table:
member_casual | rideable_type | n | prop | ymax |
---|---|---|---|---|
casual | classic_bike | 68941 | 0.660 | 0.660 |
casual | docked_bike | 14503 | 0.139 | 0.799 |
casual | electric_bike | 20990 | 0.201 | 1 |
member | classic_bike | 75455 | 0.816 | 0.816 |
member | electric_bike | 17008 | 0.184 | 1 |
Using the geom_rect function, 'ymax' will set the top of each rectangle.
So, i assign the 'ymin', to set the bottom of each rectangle:
subdata.frame$ymin <- c(0, head(subdata.frame$ymax, n=-1))
So, I run the ggplot function:
ggplot(subdata.frame, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=rideable_type)) +
geom_rect() +
scale_fill_brewer(palette=4) +
facet_grid(~member_casual) +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme_void()
Finally, I have the plot below. Note that the member donut chart is incomplete: plot error
The issue is that using subdata.frame$ymin <- c(0, head(subdata.frame$ymax, n=-1))
to compute the ymin
you did not take the grouping by member type into account.
First, to reproduce your issue:
library(ggplot2)
subdata.frame$ymin <- c(0, head(subdata.frame$ymax, n=-1))
ggplot(subdata.frame, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=rideable_type)) +
geom_rect() +
scale_fill_brewer(palette=4) +
facet_grid(~member_casual) +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme_void()
To fix that you could use dplyr::lag
as already suggested by @RuiBarradas and to group your data by member_casual
when doing so:
library(dplyr)
subdata.frame <- subdata.frame %>%
group_by(member_casual) %>%
mutate(ymin = lag(ymax, default = 0))
ggplot(subdata.frame, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=rideable_type)) +
geom_rect() +
scale_fill_brewer(palette=4) +
facet_grid(~member_casual) +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme_void()
DATA
subdata.frame <- data.frame(
stringsAsFactors = FALSE,
member_casual = c("casual", "casual", "casual", "member", "member"),
rideable_type = c("classic_bike","docked_bike",
"electric_bike","classic_bike","electric_bike"),
n = c(68941L, 14503L, 20990L, 75455L, 17008L),
prop = c(0.66, 0.139, 0.201, 0.816, 0.184),
ymax = c(0.66, 0.799, 1, 0.816, 1)
)