Home > Enterprise >  R ggplot: Combine a barplot and a line chart from a long dataset
R ggplot: Combine a barplot and a line chart from a long dataset

Time:01-30

I have a wide dataset that records the blood glucose values from 10 subjects.

library(dplyr) 

df_wide = data.frame(
  ID = seq(1, 10),
  gender = sample(0:1, 10, replace = T),
  glucose_0 = sample(100:125, 10, replace = T),
  glucose_60 = sample(180:200, 10, replace = T),
  glucose_120 = sample(130:160, 10, replace = T),
  glucose_180 = sample(100:125, 10, replace = T)
) 

I then transformed it into a long dataset using gather:

df_long = df_wide %>% 
  gather("glucose_0", "glucose_60", "glucose_120", "glucose_180", key = Time, value = glucose) %>% 
  arrange(ID)

To show how the glucose values changed from 0 min to 180 min, I then made the following line chart:

df_long %>% 
  ggplot(aes(x = Time, y = glucose, group = ID))   
  geom_line(aes(linetype = as.factor(gender)))  
  geom_point()  
  theme_classic()  
  scale_x_discrete(limits = c("glucose_0", "glucose_60", "glucose_120", "glucose_180"),
                   labels = c("0", "60", "120", "180"))  
  theme(legend.position = "bottom")  
  labs(
    x = "Time",
    y = "Glucose",
    fill = "Gender"
  ) 

Finally, to show the glucose at each time point, I also made a barplot:

df_long %>% 
  ggplot(aes(x = Time, y = glucose, fill = as.factor(gender)))   
  geom_bar(stat = 'identity', position = position_dodge())  
  theme_classic()  
  scale_x_discrete(limits = c("glucose_0", "glucose_60", "glucose_120", "glucose_180")) 

My question is: How to combine the line chart and the barplot into one figure that looks like this? Goal

CodePudding user response:

In order to plot the mean glucose levels as both bar and line

df_long %>%
  group_by(gender, Time) %>% 
  mutate(glucose = mean(glucose)) %>% 
  ggplot(aes(x = Time, y = glucose, fill = as.factor(gender)))   
  geom_bar(stat = 'identity', position = position_dodge())  
  geom_line(aes(linetype=as.factor(gender), group=ID))  
  theme_classic()  
  scale_x_discrete(limits = c("glucose_0", "glucose_60", "glucose_120", "glucose_180")) 

enter image description here

CodePudding user response:

Are you looking for such a solution?

library(tidyverse)

df_wide %>% 
  pivot_longer(
    starts_with("glucose")
  ) %>% 
  mutate(gender = fct_inorder(factor(gender))) %>% 
  arrange(ID) %>% 
  ggplot(aes(x = name, y = value))   
  geom_col(aes(fill = gender, group=gender), width = 0.5, position = position_dodge()) 
  stat_summary(aes(group = gender), fun = mean, geom = 'line', size=1, alpha=0.9)  
  stat_summary(aes(group = gender), fun = mean, geom = 'point', size=2, alpha=0.9)  
  theme_classic()  
  scale_x_discrete(limits = c("glucose_0", "glucose_60", "glucose_120", "glucose_180"),
                   labels = c("0", "60", "120", "180"))  
  theme(legend.position = "bottom")  
  labs(
    x = "Time",
    y = "Glucose",
    fill = "Gender"
  ) 

enter image description here

  •  Tags:  
  • Related