In ggplot2 – issue with overlay of lines and errorbars, I suggested an answer that used lapply(.) to produce groups of geoms in a particular order, so that points/lines/errorbars for each level would be layered together. However, it appears that the factor order of levels is lost in the process.
This first code block generates the original plot: the order of elements in the legend is correct (but the geom layering is not, this is before my answer).
d2 <- structure(list(time_serie = c(1.3, 2.3, 3.3, 1.2, 2.2, 3.2, 1.1, 2.1, 3.1), treatment = structure(c(3L, 3L, 3L, 2L, 2L, 2L, 1L, 1L, 1L), .Label = c("HIGH", "MEDIUM", "LOW"), class = "factor"), mean_value = c(2.93173234758433, 5.60600521659944, 7.85452806402463, 5.25617444992531, 3.6695183776319, 4.57195128872991, 3.24979097663891, 4.59766399173532, 4.39298335579224), SE_value = c(0.232090045905285, 0.585377662916667, 0.679289569404838, 1.3130008364543, 0.849157470954342, 1.22194305280708, 1.21458843275054, 1.0620028602709, 0.949469468240659 )), row.names = c(NA, -9L), class = "data.frame")
library(ggplot2)
ggplot(aes(x = time_serie, y = mean_value, color = treatment, group = treatment), data = d2) +
geom_errorbar(aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value),
width = 0.2, size = 2) +
geom_point(aes(), size = 3) +
geom_line(aes(color = treatment), size = 2)
The answer I suggested uses lapply to control the order of the layers. However, in doing so, the order of treatment levels is lost:
ggplot(aes(x = time_serie, y = mean_value, color = treatment, group = treatment), data = d2) +
lapply(rev(levels(d2$treatment)), function(trtmnt) {
list(
geom_errorbar(data = ~ subset(., treatment == trtmnt),
aes(ymin = mean_value - SE_value, ymax = mean_value + SE_value),
width = 0.2, size = 2),
geom_point(data = ~ subset(., treatment == trtmnt), aes(), size = 3),
geom_line(data = ~ subset(., treatment == trtmnt), size = 2)
)
})
Note that the legend has the levels in the incorrect order.
levels(d2$treatment)
# [1] "HIGH" "MEDIUM" "LOW"
The answer to "how to change legend element order" is almost always "use factor(., levels=.)", but that's been done and it is ignored.
Why is the order lost, and more importantly how can we retain the order in the legend (when layers are added as lists-of-geoms)?
(PS: if you have comments on how to better control layering, please discuss it in the previous question. This question is based on the requirement of using lapply for some reason to generate geoms, and therefore how to prevent that process from dropping factor levels. Thanks!)


