使用coord_flip()函数的ggplot2条形图中图例条目的顺序

15
我是一名有用的助手,可以为您翻译文本。

我正在努力在使用R中的ggplot2制作的图形中获得正确的变量排序。

假设我有一个数据框如下:

set.seed(1234)
my_df<- data.frame(matrix(0,8,4))
names(my_df) <- c("year", "variable", "value", "vartype")
my_df$year <- rep(2006:2007)
my_df$variable <- c(rep("VX",2),rep("VB",2),rep("VZ",2),rep("VD",2))
my_df$value <- runif(8, 5,10) 
my_df$vartype<- c(rep("TA",4), rep("TB",4))

生成以下表格:

  year variable    value vartype
1 2006       VX 5.568517      TA
2 2007       VX 8.111497      TA
3 2006       VB 8.046374      TA
4 2007       VB 8.116897      TA
5 2006       VZ 9.304577      TB
6 2007       VZ 8.201553      TB
7 2006       VD 5.047479      TB
8 2007       VD 6.162753      TB

有四个变量(VX, VB, VZ和VD),属于两种不同的变量类型组(TA和TB)。

我想画出这些值作为水平条形图,首先按照变量组再按照变量名称垂直排序,分面显示年份,将值放在x轴上,填充颜色对应变量组。(即在这个简化的例子中,顺序应为VB、VX、VD、VZ)

1) 我的第一次尝试是尝试以下方法:

ggplot(my_df,        
    aes(x=variable, y=value, fill=vartype, order=vartype)) +
       # adding or removing the aesthetic "order=vartype" doesn't change anything
     geom_bar() + 
     facet_grid(. ~ year) + 
     coord_flip()

然而,变量按照字母顺序相反的顺序列出,而不是按照 vartype 排序: order=vartype 美学效果被忽略。

enter image description here

2)根据我昨天发布的类似问题的答案,我尝试了以下操作,基于Order Bars in ggplot2 bar graph帖子:

my_df$variable <- factor(
  my_df$variable, 
  levels=rev(sort(unique(my_df$variable))), 
  ordered=TRUE
)

这种方法确实可以按字母顺序垂直排列绘图中的变量,但忽略了变量应该首先按变量组进行排序(TA变量在顶部,TB变量在底部)。

enter image description here

3) 下面的代码与2相同(见上文):

my_df$vartype <- factor(
  my_df$vartype, 
  levels=sort(unique(my_df$vartype)), 
  ordered=TRUE
)

...这与第一种方法存在相同的问题(变量按反向字母顺序列出,组被忽略)

4)另一种方法基于对Order Bars in ggplot2 bar graph的原始答案,也会得到与上述第2种方法相同的结果

my_df <- within(my_df, 
                vartype <- factor(vartype, 
                levels=names(sort(table(vartype),
                decreasing=TRUE)))
                ) 

我对这个事实感到困惑,尽管有几种方法,美学order=vartype仍被忽略。不过,它似乎在一个无关的问题中起作用:http://learnr.wordpress.com/2010/03/23/ggplot2-changing-the-default-order-of-legend-labels-and-stacking-of-data/

希望问题清楚,并欢迎任何建议。

Matteo

我昨天发布了一个类似的问题,但不幸的是,我在描述问题和提供可复制的示例时犯了几个错误。 自那以来,我听取了几个建议,并在stakoverflow上彻底搜索了类似的问题并应用了我所知道的每种建议组合,但都没有成功。 我再次发布问题,希望能够解决我的问题,并希望对其他人有所帮助。


2
这不是stackoverflow.com/q/5208679/602276的重复。请仔细阅读问题。 - MatteoS
1
学会提供可重现的代码,加一分。 - Roman Luštrik
@MatteoS 请在此加入 R 聊天组:http://chat.stackoverflow.com/rooms/106/r - Andrie
@MatteoS 在聊天组中的共识是,您有一个关于以非字母顺序对向量进行排序的有趣问题要问。我建议您发布一个新问题来解决您的排序问题。简化您的示例,删除 ggplot 代码,并仅就排序提出新问题。 - Andrie
3
更一般地,我认为在对变量排序时,与coord_flip()有关的问题存在。在我的原始数据框中(不是上面显示的那个),图例组的顺序是正确的,与数据框中的顺序相对应,但变量的垂直顺序是颠倒的。(虽然这个图表在概念上不同,但问题类似于这个 http://learnr.files.wordpress.com/2010/03/order_variable-0041.png?w=600)。据我所见,这不仅仅是数据框的排序问题,而且还涉及到ggplot2中的顺序反转问题,可能与coord_flip有关。 - MatteoS
显示剩余11条评论
1个回答

11

这与ggplot关系不大,而是一个有关生成变量排序以重新排列因子级别的问题。以下是使用各种函数实现数据的示例:

set.seed(1234)
df2 <- data.frame(year = rep(2006:2007), 
                  variable = rep(c("VX","VB","VZ","VD"), each = 2),
                  value = runif(8, 5,10),
                  vartype = rep(c("TA","TB"), each = 4))
请注意,这种方式中的variablevartype是因子。如果它们不是因子,ggplot()将强制转换它们,然后您将得到字母顺序。我以前说过,现在也无疑会再次说; 在开始绘图/进行数据分析之前,首先将数据格式正确化。 您需要以下排序:
> with(df2, order(vartype, variable))
[1] 3 4 1 2 7 8 5 6

需要注意的是,我们首先根据vartype进行排序,然后再在vartype的级别内根据variable进行排序。如果我们使用这种方式重新排序variable的级别,我们将得到:

> with(df2, reorder(variable, order(vartype, variable)))
[1] VX VX VB VB VZ VZ VD VD
attr(,"scores")
 VB  VD  VX  VZ 
1.5 5.5 3.5 7.5 
Levels: VB VX VD VZ

(忽略attr(,"scores")部分,集中关注Levels)。这个顺序是正确的,但是ggplot()会从下往上绘制它们,而你想要从上往下。我对ggplot()不够熟悉,不知道是否可以控制这一点,因此我们还需要在调用order()时使用decreasing = TRUE来反转排序。

将所有内容组合在一起,我们得到:

## reorder `variable` on `variable` within `vartype`
df3 <- transform(df2, variable = reorder(variable, order(vartype, variable,
                                                         decreasing = TRUE)))

当与您的绘图代码一起使用时:

ggplot(df3, aes(x=variable, y=value, fill=vartype)) +
       geom_bar() + 
       facet_grid(. ~ year) + 
       coord_flip()

会生成这个图表:

重新排序的条形图


2
谢谢你的解决方案!它有效。然而,我经过深入搜索后发现,我的原始问题是使用coord_flip()时常见的一个特殊情况。 - MatteoS
1
@MatteoS 你现在明白为什么人们觉得这是另一个重复的问题了吗?答案是一样的 - 重新排列因子的级别以获得所需的顺序。问题在于如何推导出这个排序。所有的ggplot代码都是多余和分散注意力的。将问题归结到基本层面并告诉我们您确切想要什么是有帮助的。Andrie的回答几乎完美,直到您在评论中提到不想手动输入排序。 - Gavin Simpson
3
现在我明白了,但是 ggplot2 是问题所在。使用 coord_flip() 后,轴会翻转,原本从左到右排列的变量会被重新排序为从下到上,而图例没有相应更改。 - MatteoS
1
@MatteoS 问吧,但是考虑到通常解决方案可以按照你想要的顺序获取因子水平,我并没有看到这样做的必要性。 - Gavin Simpson
6
scale_fill_discrete(guide = guide_legend(reverse=TRUE)) 相当于在图例中反转顺序,相当于 top.down=TRUE。请注意,翻译保持原意并简洁易懂,不包含其他内容。 - mlt
显示剩余13条评论

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