使用ggplot2绘制分面点图时如何调整因子变量的顺序

8

我正在尝试在ggplot2的facet dotplot中更改绘图顺序,但我无法使其正常工作。这是我的融合数据集:

> London.melt
                      country medal.type count
1                 South Korea       gold    13
2                       Italy       gold     8 
3                      France       gold    11
4                   Australia       gold     7
5                       Japan       gold     7
6                     Germany       gold    11
7  Great Britain & N. Ireland       gold    29
8          Russian Federation       gold    24
9                       China       gold    38
10              United States       gold    46
11                South Korea     silver     8
12                      Italy     silver     9
13                     France     silver    11
14                  Australia     silver    16
15                      Japan     silver    14
16                    Germany     silver    19
17 Great Britain & N. Ireland     silver    17
18         Russian Federation     silver    26
19                      China     silver    27
20              United States     silver    29
21                South Korea     bronze     7
22                      Italy     bronze    11
23                     France     bronze    12
24                  Australia     bronze    12
25                      Japan     bronze    17
26                    Germany     bronze    14
27 Great Britain & N. Ireland     bronze    19
28         Russian Federation     bronze    32
29                      China     bronze    23
30              United States     bronze    29

这是我的绘图命令:

qplot(x = count, y = country, data = London.melt, geom = "point", facets = medal.type ~.)

我得到的结果如下所示:

R plot

在这个图中,各个分面已经按照我想要的顺序出现了。但是,在每个分面内部,我希望按计数排序。也就是说,对于每种奖牌类型,我希望赢得该奖牌数量最多的国家排在最上面,以此类推。如果我们只看金牌等情况时,我通常会在因子“country”上使用“reorder”函数按“count”排序,而在这个例子中不起作用。
如果您有任何建议,我将非常感激。

2
请使用 dput(London.melt) 显示您的数据集,以便轻松导入。 - ROLO
3个回答

11

这里有一个使用paste、自由比例尺和一些重新标记的解决方案

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)

输入图像描述


@ttmaccer 你可以通过使用 within 来减少输入量:London.melt <- within(London.melt, medal.type <- factor(medal.type, ... )) - Andrie

1
这显然有些晚了,我所做的一些事情可能在6年前还不存在,但我在完成类似任务时遇到了这个问题。我总是不愿意用向量设置刻度标签——使用一个可以操作原始标签的函数更加安全。
为此,我正在创建一个基于国家和奖牌的因子ID列,并使用一些分隔符字符来分割它们,该字符在这两列中都不存在——在这种情况下,_有效。然后使用forcats::fct_reorder,可以按count对该列进行排序。该列的最后几个级别如下,应与具有最高计数的国家+奖牌组合相对应。
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"

然后将此ID用作y轴。单独使用时,您将拥有包含奖牌类型的非常长的标签。由于唯一的分隔符,您可以编写一个内联函数来删除分隔符和其后的任何单词字符,只留下国家。将facet规范移动到facet_wrap函数中,使您可以设置自由y比例尺。
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)


0

这是我用qplot能做到的最好的了。不完全是你要求的,但更接近了。哎呀,我看到你已经发现了。

q <- qplot(x = count, y = reorder(country, count), data = London.melt, geom = "point", facets = medal.type ~.)

这里是一个 dput 版本,以便其他人可以改进:

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"))

就到了我来的地方。我也卡住了。我也试过使用“order”的美学效果,但不幸的是,似乎没有什么作用。 - ROLO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接