Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Force facet wrapped plots to center at a common point, namely 0

I’m sure there’s a more elegant way to get to this plot, but here goes with some of the data I have to work with

score <- c(1, 2, 3, 4, 5, "X")
group1 <- c(0,0,5,-0.2,-4.9,0)
group2 <- c(0.1,0,-1.2,0.4,0.6,0.1)
group3 <- c(0.1,0,3.4,2.9,-6.4,0)
group4 <-c(0,0,-0.9,-0.3,1.3,0)

data <- data.frame(score=as.factor(score), group1=group1, group2=group2, group3=group3, group4=group4)

data_long <- pivot_longer(data, c(group1, group2, group3, group4))
sig <- rep(0, 24)
sig[c(3, 9, 11, 15, 17, 19)] <- 1
sig <- as.factor(sig)
data_long <- cbind(data_long, sig)


bars <- data_long %>% filter(score != 2,
                             score != "X") %>%
  ggplot(aes(x = name, y=value, fill=sig))+ 
  geom_bar(stat="identity") +
  coord_flip() +
  scale_fill_manual(values=c("grey", "black")) +
  facet_wrap(~rating, scales = "free_x") +
  theme(legend.position = "none")

print(bars)

This gives the following plot

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What this represents are deviations from expected value for each of the score levels for the four different groups. (it’s a "feature" of the problem that we don’t care about 2’s and X’s). Those measures with a 1 in the sig column are statistically significant.

What I’d like to do is have each of the facets centered at 0.

I tried following methods found here but couldn’t get things to work…in particular I kept getting Error: Discrete value supplied to continuous scale when attempting the method that made use of geom_blank()

>Solution :

You can provide a function to the limits of a scale. In the example below, note that I’ve used score instead of rating for facets, and circumvented the coord_flip() by swapping the x- and y-variables. The function below is in the so called ‘lambda syntax’, but you can use regular function(x) c(-1, 1) * max(abs(x)) too.

library(tidyverse)

# Data prep as in original question
# data_long <- ...


bars <- data_long %>% filter(score != 2,
                             score != "X") %>%
  ggplot(aes(x = value, y=name, fill=sig))+ 
  geom_bar(stat="identity") +
  scale_fill_manual(values=c("grey", "black")) +
  scale_x_continuous(
    limits = ~ c(-1, 1) * max(abs(.x))
  ) +
  facet_wrap(~score, scales = "free_x") +
  theme(legend.position = "none") 

bars

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading