简体   繁体   中英

Regression coefficients as bar chart and by group: ggplot

The following data is the output of my linear regression comparing intervention versus control group for a number of nutrients for 4 different time points. 在此处输入图像描述 How can I make a horizontal barplot for each nutrient showing:

  1. all 4 timepoints (column: Followup) as bars (column: inter_val) and in a specific order of nutrients
  2. add 95% CI bars on top of the bars (columns: inter_lowCI, inter_upCI)
  3. the top most bar should be baseline, followed by 6 months, 24 months, and 48 months
  4. add * or ** or *** to show the p-value significance (column: p_Intervention)
  5. do the same thing for the control group (showing no p value significance)

This is what I did and was unable to do the above points.

ggplot(plot1, aes(factor(Nutrient), inter_val, fill = Followup)) + 
 geom_bar(stat="identity", position = "dodge") + 
 geom_errorbar(aes(ymin=inter_val-inter_lowCI, ymax=inter_val+inter_upCI), width=1, size=1) + 
 scale_fill_brewer(palette = "Set1") +
 coord_flip()
plot1 <- structure(list(Followup = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 
3L, 4L), .Label = c("Baseline", "6 months", "24 months", "48 months"
), class = "factor"), Nutrient = structure(c(1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L), .Label = c("Protein_g", "Fat_g"), class = "factor"), 
    estimate_control = c(61.00596313, 65.53883145, 73.31875608, 
    78.91867614, 67.0690134, 60.01715111, 62.63232916, 82.27888654
    ), lowCIcontrol = c(50.941157, 53.03671101, 59.93245069, 
    63.98993695, 53.7771638, 44.59304192, 45.56292816, 61.10072183
    ), upCIcontrol = c(71.07076925, 78.0409519, 86.70506146, 
    93.84741533, 80.36086301, 75.44126031, 79.70173015, 103.45705126
    ), inter_val = c(60.10474197, 60.46426229, 71.52401348, 77.26970387, 
    66.22599924, 40.25131748, 47.51238789, 74.312322), inter_lowCI = c(48.07336716, 
    45.44116548, 55.56009104, 59.53520327, 50.33704695, 21.7170307, 
    27.15616668, 49.15385617), inter_upCI = c(72.13611677, 75.48735912, 
    87.4879359, 95.00420447, 82.11495155, 58.78560428, 67.86860908, 
    99.47078784), p_Intervention = c(0.36882348, 0.00008475, 
    0.17207734, 0.24888026, 0.5243924, 0, 0, 0.00009439)), row.names = c(5L, 
6L, 7L, 8L, 13L, 14L, 15L, 16L), class = "data.frame")

Thanks for the help!

You could do the control and treatment in the same plot, too:

library(dplyr)
library(tidyr)
plot1 <- plot1 %>% 
  mutate(Followup = factor(Followup, levels=rev(c("Baseline", "6 months", 
                                              "24 months", "48 months")))) %>% 
  setNames(c("Followup", "Nutrient", "est_control", "low_control", "up_control", 
             "est_val", "low_val", "up_val", "p_Intervention")) 

plot1 <- plot1 %>% 
  pivot_longer(est_control:up_val, 
               names_pattern="(.*)_(.*)", 
               names_to = c("type", "treat"), 
               values_to="vals") %>% 
  pivot_wider(names_from="type", values_from="vals") %>% 
  mutate(treat = factor(treat, levels=c("val", "control"), 
                        labels=c("Treatment", "Control"))) %>% 
  mutate(sig = case_when(
    p_Intervention < .1 & p_Intervention >= .05 & treat == "Treatment" ~ "*", 
    p_Intervention < .05 & p_Intervention >= .01 & treat == "Treatment" ~ "**", 
    p_Intervention < .01 & treat == "Treatment" ~ "***", 
    TRUE ~ ""
  ))

ggplot(plot1, aes(x=Nutrient, y=est, fill=Followup)) + 
  geom_bar(stat="identity", position="dodge") + 
  geom_errorbar(aes(ymin=low, ymax=up), position=position_dodge(width=.9), width=.15) + 
  geom_text(aes(y=up + 10, label=sig), position=position_dodge(width=.9)) + 
  facet_wrap(~treat) + 
  scale_fill_brewer(palette="Set1") + 
  labs(y="Estimate", x="") +
  coord_flip() 

在此处输入图像描述


Edit: Answer to question in comments

The question in the comments was how to use geom_text() to add an estimate and CI? The answer is you first have to make a variable that has the estimate and confidence interval text in it. Then you can use that variable as the label aesthetic. Here's an example:

plot1 <- plot1 %>% mutate(est_ci = sprintf("%.2f \n(%.2f, %.2f)", est, low, up))
ggplot(plot1, aes(x=Nutrient, y=est, fill=Followup)) + 
  geom_bar(stat="identity", position="dodge") + 
  geom_errorbar(aes(ymin=low, ymax=up), position=position_dodge(width=.9), width=.15) + 
  geom_text(aes(y=up + 10, label=sig), position=position_dodge(width=.9)) + 
  geom_text(aes(y=15, label=est_ci), col="white",position=position_dodge(width=.9), size=4, vjust=1) + 
  facet_wrap(~treat) + 
  scale_fill_brewer(palette="Set1") + 
  labs(y="Estimate", x="") +
  coord_flip() 

ggsave("test.png", height=8, width=12, units="in", dpi=150)

在此处输入图像描述

Something like this?

library(ggsignif)
plot1 = plot1 %>% 
  mutate(sig = case_when(p_Intervention < 0.01 ~ "***",
                         p_Intervention < 0.05 ~ "**",
                         p_Intervention < 0.1 ~ "*",
                         TRUE ~ ""))

ggplot(plot1, aes(factor(Nutrient), inter_val, fill = fct_rev(Followup))) + 
  geom_bar(stat="identity", position = "dodge") + 
  geom_errorbar(aes(ymin=inter_val-inter_lowCI, ymax=inter_val+inter_upCI), width=1, size=1,position="dodge") + 
  coord_flip() + 
  geom_text(aes(x=factor(Nutrient),y = inter_val+inter_upCI + 10,label=sig,group=fct_rev(Followup)),position = position_dodge(width=1)) + 
  scale_fill_brewer(palette = "Set1")

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM