10 minutes worth of hacky geom, but a start in the right direction that should get you far enough to go at it alone. i can try a bit more when i get a chance.
library(gapminder)
library(ggplot2)
library(rlang)
library(dplyr)
#> Warning: package 'dplyr' was built under R version 3.5.1
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tidyr)
x <- gapminder %>%
dplyr::mutate(pop=as.numeric(pop))%>%
dplyr::group_by(continent, year) %>%
dplyr::summarise(populations = sum(pop)) %>%
tidyr::spread(continent, populations) %>%
dplyr::mutate(
year = factor(year)
)
geom_cbar <- function(mapping = NULL, data = NULL, stat = "identity", position = "stack",
..., width = NULL, binwidth = NULL, na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
# create the difference
diff_data <- data%>%
dplyr::mutate(
diff = !!mapping$g1 - !!mapping$g2,
grey = (!!mapping$g1 + !!mapping$g2) - diff,
area = ifelse((diff) > 0,rlang::quo_name(mapping$g1),rlang::quo_name(mapping$g2)),
diff = abs(diff)
)
# create the comparison
comp_data <- diff_data%>%
dplyr::select(!!mapping$x,area,diff,grey)%>%
tidyr::gather(type,value,-c(!!mapping$x,area))%>%
dplyr::mutate(
comparison = sprintf('%s_%s',type,area),
comparison = ifelse(grepl('^grey',comparison),NA,comparison),
comparison = factor(comparison, labels = c(rlang::quo_name(mapping$g1),
rlang::quo_name(mapping$g2))
)
)
mapping$g1 <- NULL
mapping$g2 <- NULL
layer(data = comp_data, mapping = mapping, stat = stat, geom = GeomBar,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(width = width, na.rm = na.rm, ...)
)
}
p <- ggplot() +
geom_cbar(aes(x=year,y=value,fill=comparison,g1 = Americas, g2 = Europe),data=x)
p

p + scale_fill_discrete(breaks = c('Americas','Europe'))

ggplot() +
geom_cbar(aes(x=year,y=value,fill=comparison,g1 = Americas, g2 = Africa),data=x)

Created on 2018-08-27 by the reprex
package (v0.2.0).