Context
I used ggplot to draw a grouped error bar graph. I want to connect the points with lines within each group.
I tried to use geom_line(), but the result is not what I want.
Question
Is there any way to connect the points within each group with a line, like the red line in the figure below.
Reproducible Code
dat_a = structure(list(exposure = c("HDL", "HDL", "HDL", "HDL", "HDL",
"HDL", "HDL", "HDL", "HDL"), event = c("mRS", "mRS", "mRS", "mRS",
"mRS", "mRS", "mRS", "mRS", "mRS"), model = structure(c(1L, 1L,
1L, 2L, 2L, 2L, 3L, 3L, 3L), levels = c("low", "middle", "high"
), class = "factor"), group = c("middle", "low", "high", "middle",
"low", "high", "middle", "low", "high"), margin = c(0.292, 0.372,
0.349, 0.25, 0.336, 0.281, 0.252, 0.35, 0.278), LL = c(0.273,
0.327, 0.308, 0.23, 0.287, 0.235, 0.226, 0.285, 0.22), UL = c(0.311,
0.417, 0.391, 0.27, 0.385, 0.326, 0.278, 0.415, 0.336)), row.names = c(NA,
-9L), class = c("tbl_df", "tbl", "data.frame"))
pd = position_dodge(.7)
ggplot(dat_a, aes(colour=group, y=margin, x=model, group=group))
geom_point(position=pd,shape=16,size=4)
geom_errorbar(aes(ymax = UL, ymin=LL), position=pd,width=0.2,size=1.1)
labs(title = "", x="", y="Marginal probability of poor prognosis")
guides(color=guide_legend(title="HDL cholesterol level"))
scale_color_jama()
theme_classic()
theme(axis.title =element_text(size=14),axis.text = element_text(size = 12),
legend.text=element_text(size=12),legend.title = element_text(size=12),
legend.position = 'right') ylim(0.2,0.5)
CodePudding user response:
Dodging and lines is always a bit tricky. The issue is that on the one hand we want the lines to be grouped by model but on the other hand we want them to be grouped by group for the dodging. TBMK there is no way to achieve that via dodging and the group aes. Instead I would go for manual dodging which requires to compute the x positions for the geom_line manually. To this end convert your model and group columns to numerics first. Second, rescale the group_num to a range of -1 to 1. This resealed column will be used to "shift" the points for each category of model. Third, compute the amount of the shift which is simply the width used for dodging divided by the number of groups:
library(ggplot2)
library(ggsci)
dw <- .7
dw_line <- dw / length(unique(dat_a$group))
pd <- position_dodge(width)
dat_a$model_num <- as.numeric(factor(dat_a$model))
dat_a$group_num <- as.numeric(factor(dat_a$group))
dat_a$group_num <- scales::rescale(dat_a$group_num, to = c(-1, 1))
ggplot(dat_a, aes(colour = group, y = margin, x = model, group = group))
geom_point(position = pd, shape = 16, size = 4)
geom_errorbar(aes(ymax = UL, ymin = LL), position = pd, width = 0.2, size = 1.1)
geom_line(aes(x = model_num dw_line * group_num, group = model), color = "red", size = 2)
labs(title = "", x = "", y = "Marginal probability of poor prognosis")
guides(color = guide_legend(title = "HDL cholesterol level"))
scale_color_jama()
theme_classic()
theme(
axis.title = element_text(size = 14), axis.text = element_text(size = 12),
legend.text = element_text(size = 12), legend.title = element_text(size = 12),
legend.position = "right"
)
ylim(0.2, 0.5)


