I\'m trying to change the plotting order within facets of a faceted dotplot in ggplot2, but I can\'t get it to work. Here\'s my melted dataset:
> London.m
This is the best I can do with qplot. Not exactly what you asked for but closer. OOOPs I see you already figured that out.
q <- qplot(x = count, y = reorder(country, count), data = London.melt, geom = "point", facets = medal.type ~.)
Here's a dput
version so others can improve:
dput(London.melt)
structure(list(country = structure(c(9L, 6L, 3L, 1L, 7L, 4L,
5L, 8L, 2L, 10L, 9L, 6L, 3L, 1L, 7L, 4L, 5L, 8L, 2L, 10L, 9L,
6L, 3L, 1L, 7L, 4L, 5L, 8L, 2L, 10L), .Label = c("Australia",
"China", "France", "Germany", "Great Britain & N. Ireland", "Italy",
"Japan", "Russian Federation", "South Korea", "United States"
), class = "factor"), medal.type = structure(c(2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("bronze",
"gold", "silver"), class = "factor"), count = c(13L, 8L, 11L,
7L, 7L, 11L, 29L, 24L, 38L, 46L, 8L, 9L, 11L, 16L, 14L, 19L,
17L, 26L, 27L, 29L, 7L, 11L, 12L, 12L, 17L, 14L, 19L, 32L, 23L,
29L)), .Names = c("country", "medal.type", "count"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24",
"25", "26", "27", "28", "29", "30"))
Here a solution using paste, free scales and some relabeling
library(ggplot2)
London.melt$medal.type<-factor(London.melt$medal.type, levels = c("gold","silver","bronze"))
# Make every country unique
London.melt$country_l <- with(London.melt, paste(country, medal.type, sep = "_"))
#Reorder the unique countrys
q <- qplot(x = count, y = reorder(country_l, count), data = London.melt, geom = "point") + facet_grid(medal.type ~., scales = "free_y")
# Rename the countries using the original names
q + scale_y_discrete("Country", breaks = London.melt$country_l, label = London.melt$country)
This is obviously quite late, and some of what I'm doing may have not been around 6 years ago, but I came across this question while doing a similar task. I'm always reluctant to set tick labels with a vector—it feels safer to use a function that can operate on the original labels.
To do that, I'm creating a factor ID column based on the country and the medal, with some delimiter character that doesn't already appear in either of those columns—in this case, _
works. Then with forcats::fct_reorder
, I can order that column by count
. The last few levels of this column are below, and should correspond to the country + medal combinations with the highest counts.
library(tidyverse)
London_ordered <- London.melt %>%
mutate(id = paste(country, medal.type, sep = "_") %>%
as_factor() %>%
fct_reorder(count, .fun = min))
levels(London_ordered$id) %>% tail()
#> [1] "Great Britain & N. Ireland_gold" "United States_silver"
#> [3] "United States_bronze" "Russian Federation_bronze"
#> [5] "China_gold" "United States_gold"
Then use this ID as your y-axis. On its own, you'd then have very long labels that include the medal type. Because of the unique delimiter, you can write an inline function for the y-axis labels that will remove the delimiter and any word characters that come after it, leaving you with just the countries. Moving the facet specification to a facet_wrap
function lets you then set the free y-scale.
qplot(x = count, y = id, data = London_ordered, geom = "point") +
scale_y_discrete(labels = function(x) str_remove(x, "_\\w+$")) +
facet_wrap(~ medal.type, scales = "free_y", ncol = 1)