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

How to manually add a label to a specific part of my bar plot in R?

I have the following data and code…

#generate example data
rG_activity <- c("0.230", "0.335", NA, "0.368", "0.368", "0.327", "0.091", "-0.230")
rG_activity_error_intervals <- c("(-0.075, 0.335)", "(0.239, 0.631)", NA, "(0.234, 0.602)", "(0.284, 0.752)", "(0.229, 0.726)", "(-0.259, 0.340)", "(-0.311, 0.252)")
rG_task_persistence <- c("-0.304", "-0.302", "-0.309", "-0.362", "-0.345", "-0.291", "-0.062", "-0.291")
rG_task_persistence_error_intervals <- c("(-0.242, -0.266)", "(-0.268, -0.236)","(-0.256, -0.263)", "(-0.679, -0.244)", "(-0.260, -0.231)", "(-0.396, -0.086)", "(-0.272, 0.247)", "(-0.207, -0.074)")
rE_activity <- c("0.005","-0.024", NA, "0.256", "-0.225", "-0.054", "-0.013", "0.058")
rE_activity_error_intervals <- c("(-0.255, 0.266)", "(0.243, -0.291)", NA,"(-0.021, 0.333)", "(-0.298, 0.048)", "(-0.248, 0.240)", "(-0.266, 0.240)", "(-0.225, 0.241)")
rE_task_persistence <- c("0.211", "-0.006", "-0.098", "0.093", "-0.002", "0.203", "0.047", "0.205")
rE_task_persistence_error_intervals <- c("(-0.046, 0.269)", "(0.257, -0.269)", "(-0.261, 0.064)", "(-0.065, 0.251)", "(-0.274, 0.270)", "(-0.065, 0.272)", "(-0.212, 0.206)", "(-0.071, 0.280)")
rG_emotionality <- c("0.230", "0.335", "-0.309", "0.368", "0.368", "0.327", "0.091", "-0.230")
rG_emotionality_error_intervals <- c("(-0.075, 0.335)", "(0.239, 0.631)", "(-0.256, -0.263)", "(0.234, 0.602)", "(0.284, 0.752)", "(0.229, 0.726)", "(-0.259, 0.340)", "(-0.311, 0.252)")
rE_emotionality <- c("0.005","-0.024", "-0.098", "0.256", "-0.225", "-0.054", "-0.013", "0.058")
rE_emotionality_error_intervals <- c("(-0.255, 0.266)", "(0.243, -0.291)", "(-0.261, 0.064)","(-0.021, 0.333)", "(-0.298, 0.048)", "(-0.248, 0.240)", "(-0.266, 0.240)", "(-0.225, 0.241)")
age <- c("slope", "intercept", "36", "30", "24", "18", "12", "6")
df <- data.frame(age, rG_activity, rG_activity_error_intervals, rG_task_persistence, rG_task_persistence_error_intervals, rE_activity, rE_activity_error_intervals, rE_task_persistence, rE_task_persistence_error_intervals, rG_emotionality, rG_emotionality_error_intervals, rE_emotionality, rE_emotionality_error_intervals)

#produce figure
library(data.table)
setDT(df)
df_tidy <- melt(df , measure.vars = list(values=c("rG_activity","rG_task_persistence","rE_activity","rE_task_persistence", "rG_emotionality", "rE_emotionality"),
                              intervals=c("rG_activity_error_intervals","rG_task_persistence_error_intervals","rE_activity_error_intervals","rE_task_persistence_error_intervals", "rG_emotionality_error_intervals","rE_emotionality_error_intervals")))
df_tidy[ , values:=as.numeric(values)]
df_tidy[ , c("lci", "uci") := tstrsplit(gsub("[()]","",intervals),split=",",type.convert = TRUE)]
df_tidy[ , condition := c("rG_activity", "rG_persistence", "rE_activity", "rE_persistence", "rG_emotionality", "rE_emotionality")[variable]]
df_tidy[ , c("what","type") := tstrsplit(condition,split="_")]

ggplot(df_tidy) + 
  aes(x=age, y=values, ymin=lci, ymax=uci,fill=what) + 
  geom_col(position = "dodge", color = "black", width = 0.7) + 
  geom_errorbar(position=position_dodge(width=0.7),width=0.25) + 
  facet_wrap(~type, ncol=1) + 
  scale_fill_grey(
    start = 0.8,
    end = 0.475,
    na.value = "red",
    aesthetics = "fill"
  ) +
  geom_text(size=2.75,aes(label=values,y=if_else(values > 0, uci, lci) + .1 * if_else(values > 0, 1, -1)),
            position=position_dodge(width=0.7)) +
  theme_classic() + 
  labs(y = "Correlation") +
  labs(x = "") +
  theme(legend.position = "bottom", legend.title=element_blank(), legend.margin=margin(-15, 0, 0, 0)) + 
  scale_x_discrete(limits = c("6", "12", "18", "24", "30", "36", "slope", "intercept"),
                   labels = c("6"="Age 6", "12"="Age 12", "18"="Age 18", "24"="Age 24", "30"="Age 30", "36"="Age 36", "slope", "intercept"))

Which produces this figure…

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

Due to missing data, there are no bars present for activity at age 36. I would like to replace this empty space with an N/A label to get something like below. How would I modify my code to do this?

enter image description here

>Solution :

We can just add geom_text for the empty rows in df_tidy dynamically.

BLUF, add this to your code

+ geom_text(data = ~ unique(.[is.na(values),], by = c("age", "type")), label  ="N/A", y = 0)

In all,

ggplot(df_tidy) + 
  aes(x=age, y=values, ymin=lci, ymax=uci,fill=what) + 
  geom_col(position = "dodge", color = "black", width = 0.7) + 
  geom_errorbar(position=position_dodge(width=0.7),width=0.25) + 
  facet_wrap(~type, ncol=1) + 
  scale_fill_grey(
    start = 0.8,
    end = 0.475,
    na.value = "red",
    aesthetics = "fill"
  ) +
  geom_text(size=2.75,aes(label=values,y=if_else(values > 0, uci, lci) + .1 * if_else(values > 0, 1, -1)),
            position=position_dodge(width=0.7)) +
  theme_classic() + 
  labs(y = "Correlation") +
  labs(x = "") +
  theme(legend.position = "bottom", legend.title=element_blank(), legend.margin=margin(-15, 0, 0, 0)) + 
  scale_x_discrete(limits = c("6", "12", "18", "24", "30", "36", "slope", "intercept"),
                   labels = c("6"="Age 6", "12"="Age 12", "18"="Age 18", "24"="Age 24", "30"="Age 30", "36"="Age 36", "slope", "intercept")) + 
  geom_text(data = ~ unique(.[is.na(values),],
            by = c("age", "type")), label = "N/A", y = 0)

ggplot with "N/A" label

I’m using the rlang-style ~-function for data=, subsetting the data as it was passed to ggplot(.). While in this example we could easily use df_tidy directly, there are many users who %>%-pipe data into ggplot, and the risk of using the raw dataframe there is that columns are changed or not available. The use of . in the data=~-expression is that it is updated to what ggplot knows.

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