James Azam
James Azam

Reputation: 98

lollipop plot with sorting within group

I am trying to create a lollipop plot with a dataset that looks something like this:

set.seed(123)
example_df <- data.frame(strategy = as.factor(rep(LETTERS[1:5], each = 2)), 
                         mt_equip = as.factor(rep(c('r', 'v'), times = 5)), 
                         cc = as.factor(c('cc', 'cc', 'no_cc', 'no_cc', 'part_cc', 'part_cc', 'cc', 'cc', 'no_cc', 'no_cc')), 
                         vt = as.factor(c(rep('d10', 4), rep('d1+d10', 2), rep('d1', 4))), 
                         model_ouput = rnorm(10)
                         )
example_df
   strategy mt_equip      cc     vt model_ouput
1         A        r      cc    d10 -0.56047565
2         A        v      cc    d10 -0.23017749
3         B        r   no_cc    d10  1.55870831
4         B        v   no_cc    d10  0.07050839
5         C        r part_cc d1+d10  0.12928774
6         C        v part_cc d1+d10  1.71506499
7         D        r      cc     d1  0.46091621
8         D        v      cc     d1 -1.26506123
9         E        r   no_cc     d1 -0.68685285
10        E        v   no_cc     d1 -0.44566197

My goal is to make a lollipop plot so that:

  1. they are grouped and colored by cc, with mt_equip as the shape specification.
  2. within each cc category, the lollipops are sorted from lowest to highest.
  3. the lollipops should be separated and not entangled like in the figure shown.

I tried the geom_lollipop() option from the ggalt package as follows:

library(ggalt)

option2 <- ggplot(data = example_df, 
       aes(x = reorder(cc, model_ouput))) + 
    geom_lollipop(aes(y = model_ouput,
                   shape = mt_equip,
                   color = cc),
                  size = 5) +
    scale_shape_manual(values = c(21, 24)) 
plot(option2)

This is what I get:

enter image description here

How can I:

  1. disentangle the lollipops so that each one stands alone within the cc group?
  2. sort the disentangled lollipops in (1) from lowest to highest? I tried reorder but it did not produce the designed effect as shown in the image.
  3. make the bars hollow for post-processing with color and stroke?

Thank you for your help.

Upvotes: 3

Views: 795

Answers (1)

James Azam
James Azam

Reputation: 98

Upon taking a few hints from @GregorThomas, I finally solved the problem with the following code:

library(ggalt)
library(dplyr)
library(tidyr)

set.seed(123)
example_df <- data.frame(strategy = as.factor(rep(LETTERS[1:5], each = 2)), 
                         mt_equip = as.factor(rep(c('r', 'v'), times = 5)), 
                         cc = as.factor(c('cc', 'cc', 'no_cc', 'no_cc', 'part_cc', 'part_cc', 'cc', 'cc', 'no_cc', 'no_cc')), 
                         vt = as.factor(c(rep('d10', 4), rep('d1+d10', 2), rep('d1', 4))), 
                         model_ouput = rnorm(10)
)



#the strategy variable is not unique so we make it so but combining two cols
example_df_mod <- example_df %>%
    unite(col = 'strategy', c(strategy, mt_equip), remove = F)

#make lollipop plot grouped by cc and sorted within each group 
option2 <- example_df_mod %>% 
    group_by(cc) %>% 
    arrange(model_ouput, .by_group = T) %>% 
    ggplot(aes(group = cc)) + 
    geom_lollipop(aes(x = order(cc, model_ouput), 
                      y = model_ouput,
                      shape = mt_equip,
                      color = cc),
                  size = 5) 
plot(option2)

enter image description here

Upvotes: 1

Related Questions