29769

How to generate facetted ggplot graph where each facet has ordered data?

Question:

I want to sort my factors (Condition, Parameter and SubjectID) by MeanWeight and plot MeanWeight against SubjectID such that when faceted by Condition and Parameter, MeanWeight appears in descending order. Here is my solution, which isn't giving me what I want:

dataSummary <- structure(list(SubjectID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("s001", "s002", "s003", "s004"), class = "factor"), Condition = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("1", "2", "3"), class = "factor"), Parameter = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("(Intercept)", "PrevCorr1", "PrevFail1"), class = "factor"), MeanWeight = c(-0.389685536725783, 0.200987679398502, -0.808114314421089, -0.10196105040707, 0.0274188815763494, 0.359978984195839, -0.554583879312783, 0.643791202050396, -0.145042221940287, -0.0144598460145723, -0.225804028997856, -0.928152539784374, 0.134025102103562, -0.267448309989731, -1.19980109795115, 0.0587152632631923, 0.0050656268880826, -0.156537446664213 )), .Names = c("SubjectID", "Condition", "Parameter", "MeanWeight" ), row.names = c(NA, 18L), class = "data.frame") ## Order by three variables orderWeights <- order(dataSummary$Condition, dataSummary$Parameter, dataSummary$SubjectID, -dataSummary$MeanWeight) ## Set factors to the new order. I expect this to sort for each facet when plotting, but it doesn't seem to work. conditionOrder <- dataSummary$Condition[orderWeights] dataSummary$Condition <- factor(dataSummary$Condition, levels=conditionOrder) paramOrder <- dataSummary$Parameter[orderWeights] dataSummary$Parameter <- factor(dataSummary$Parameter, levels=paramOrder) sbjOrder <- dataSummary$SubjectID[orderWeights] dataSummary$SubjectID <- factor(dataSummary$SubjectID, levels=sbjOrder) ## Plot ggplot(dataSummary, aes(x=MeanWeight, y=SubjectID)) + scale_x_continuous(limits=c(-3, 3)) + geom_vline(yintercept = 0.0, size = 0.1, colour = "#a9a9a9", linetype = "solid") + geom_segment(aes(yend=SubjectID), xend=0, colour="grey50") + geom_point(size=2) + facet_grid(Parameter~Condition, scales="free_y")

I tried a few other approaches, but they didn't work either:

dataSummary <- dataSummary[order(dataSummary$Condition, dataSummary$Parameter, dataSummary$SubjectID, -dataSummary$MeanWeight),]

or this one

dataSummary <- transform(dataSummary, SubjectID=reorder(Condition, Parameter, SubjectID, MeanWeight))

Answer1:

You can order your data and plot it. However, the labels no longer correspond to Subject ID's, but to the reordered subjects. If that is not what you want, you cannot use faceting but have to plot the parts separately and use e.g.grid.arrangeto combind the different plots.

require(plyr) ## Ordered data datOrder <- ddply(dataSummary, c("Condition", "Parameter"), function(x){ if (nrow(x)<=1) return(x) x$MeanWeight <- x$MeanWeight[order(x$MeanWeight)] x }) ## Plot ggplot(datOrder, aes(x=MeanWeight, y=SubjectID)) + scale_x_continuous(limits=c(-3, 3)) + geom_vline(yintercept = 0.0, size = 0.1, colour = "#a9a9a9", linetype = "solid") + geom_segment(aes(yend=SubjectID), xend=0, colour="grey50") + geom_point(size=2) + facet_grid(Parameter~Condition) + scale_y_discrete(name="Ordered subjects")

Recommend