使用facet_wrap时重新排序geom_bar

9
我希望你能够根据给定的变量对每个面板中的条形图进行排序。
一个简单的例子:
    library(ggplot2)
    library(plyr)

    df <- data.frame(fac = c("a", "b", "c", "e", "b", "c", "d"),             
                  val = c(1, 2, 7, 4, 5, 3, 1),
                  group = c(1, 1, 1, 1, 2, 2, 2))

    p1 <- ggplot(df, aes(x = fac, y = val)) + geom_bar() + facet_wrap(~ group, scales = "free") + coord_flip()
    p1

    p2 <- ggplot(df, aes(x = reorder(fac, val), y = val)) + geom_bar() + facet_wrap(~ group, scales = "free") + coord_flip()
    p2

p2不能满足我的需求,因为并非所有“因子水平”都出现在所有面板中。有没有已经存在的简单解决方案?

我找到的一个解决方法是(计算每个组中每个因子水平的排名)。

df2 <- ddply(df, .(group), transform, fac2 = rank(val))
df2$fac2 <- factor(df2$fac2)
p3 <- ggplot(df2, aes(x = fac2, y = val)) + facet_wrap(~ group, scales = "free") + geom_bar(stat = "identity") + coord_flip() +
  opts(panel.margin = unit(2, "lines"))
p3

我必须在这里自己设置标签。以下是一种可能的解决方案(针对此示例进行硬编码):

grid.newpage()
grob <- ggplotGrob(p3)
object.path <- grid.ls(getGrob(grob, "axis.text.y", grep = TRUE, global = TRUE), print = FALSE)$name
grob <- grid::editGrob(grob, object.path[1], label = c("ABDQ", "M", "A", "B"))
grob <- grid::editGrob(grob, object.path[2], label = c("A", "B", "EEEEX"))
grid.draw(grob)

但是还有另一个问题。我现在必须自己设置panel.margin,而且似乎不可能像我想要的那样只为所有4个边设置一个“全局”panel.margin(或者至少2个)。
问题1:是否有使用reorder的简单解决方案?
问题2:是否有使用scale_x_discrete来获取所需轴的解决方案?
问题3:我找不到需要的网格对象以操纵用于panel.margins的视口。是否有一种简单的方法来操作适当的网格对象?
有什么想法吗?
1个回答

4

我认为 grid.arrange 比尝试将自由比例尺塞进分面框架中要好得多:

library(gridExtra)
q1 <- ggplot(subset(df,group == 1),aes(x = reorder(fac,val),y = val)) + 
        geom_bar() + 
        facet_wrap(~group) + 
        coord_flip()

q2 <- q1 %+% subset(df,group == 2)

grid.arrange(q1,q2,nrow = 1)

enter image description here


非常感谢!我之前不知道有grid.arrange。 - user1901670
好的解决方案。谢谢。 - Seanosapien

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