Home > Blockchain >  Plotting geom_segment with position_dodge
Plotting geom_segment with position_dodge

Time:10-18

I have a data set with information of where individuals work at over time. More specifically, I have information on the interval at which individuals work in a given workplace.

library('tidyverse')
library('lubridate')

# individual A
a_id <- c(rep('A',1))
a_start <- c(201201)
a_end <- c(201212)
a_workplace <-c(1)

# individual B
b_id <- c(rep('B',2))
b_start <- c(201201, 201207)
b_end <- c(201206, 201211)
b_workplace <-c(1, 2)

# individual C
c_id <- c(rep('C',2))
c_start <- c(201201, 201202)
c_end <- c(201204, 201206)
c_workplace <-c(1, 2)
  
# individual D
d_id <- c(rep('D',1))
d_start <- c(201201)
d_end <- c(201201)
d_workplace <-c(1)

# final data frame
id <- c(a_id, b_id, c_id, d_id)
start <- c(a_start, b_start, c_start, d_start)
end <- c(a_end, b_end, c_end, d_end)
workplace <- as.factor(c(a_workplace, b_workplace, c_workplace, d_workplace))
mydata <- data.frame(id, start, end, workplace)

mydata_ym <- mydata %>%
  mutate(ymd_start = as.Date(paste0(start, "01"), format = "%Y%m%d"),
         ymd_end0 = as.Date(paste0(end, "01"), format = "%Y%m%d"),
         day_end = as.numeric(format(ymd_end0   months(1) - days(1), format = "%d")),
         ymd_end = as.Date(paste0(end, day_end), format = "%Y%m%d")) %>%
  select(-ymd_end0, -day_end)

I would like a plot where I can see the patterns of how long each individual works at each workplace as well as how they move around. I tried plotting a geom_segment as I have information of start and end date the individual works in each place. Besides, because the same individual may work in more than one place during the same month, I would like to use position_dodge to make it visible when there is overlap of different workplaces for the same id-time. This was suggested in this post here: Ggplot (geom_line) with overlaps

ggplot(mydata_ym)  
  geom_segment(aes(x = id, xend = id, y = ymd_start, yend = ymd_end), 
               position = position_dodge(width = 0.1), size = 2)  
  scale_x_discrete(limits = rev)  
  coord_flip()  
  theme(panel.background  = element_rect(fill = "grey97"))  
  labs(y = "time", title = "Work affiliation")

The problem I am having is that: (i) the position_dodge doesn't seem to be working, (ii) I don't know why all the segments are being colored in black. I would expect each workplace to have a different color and a legend to show up.

CodePudding user response:

If you include colour = workplace in the aes() mapping for geom_segment you get colours and a legend and some dodging, but it doesn't work quite right (it looks like position_dodge only applies to x and not xend ... ? this seems like a bug, or at least an "infelicity", in position_dodge ...

However, replacing geom_segment with an appropriate use of geom_linerange does seem to work:

ggplot(mydata_ym)  
  geom_linerange(aes(x = id, ymin = ymd_start, ymax = ymd_end, colour = workplace),
               position = position_dodge(width = 0.1), size = 2)  
  scale_x_discrete(limits = rev)  
  coord_flip()

(some tangential components omitted).

A similar approach is previously documented here — a near-duplicate of your question once the colour= mapping is taken care of ...

  • Related