ggplot2 Facet Wrap按y轴重新排序,不是x轴

时间:2018-01-10 23:33:06

标签: r ggplot2

我想绘制多面条形图并从最大值到最小值从左到右排序。我应该能够使用与此类似的代码执行此操作:

library(ggplot2)
ggplot(mpg, aes(reorder(cyl, -hwy), hwy)) + 
  geom_col() + 
  facet_wrap(~ manufacturer, scales = "free")

相反,我得到的是x轴排序,恰好是'cyl',从最小值到最大值。如何按y轴顺序下降,看起来像帕累托图?它也必须是分面的。谢谢。

2 个答案:

答案 0 :(得分:3)

如果我理解了您的问题,我们的目标是为每个hwy绘制cyl的平均高速公路mpg(manufacturer列)。在每个manufacturer中,您希望按每个cyl的平均hwy值排序x轴(cyl值)。

为此,我们需要为每个制造商单独创建图表,然后将它们一起布局。这是因为对于同一图中的不同面板,我们不能具有不同的x轴排序(在这种情况下为cyl排序)。 (更新:我已经纠正了。@ missuse'回答functions written by David Robinson的链接,基于blog post by Tyler Rinker来改变分面图中的x轴标签顺序。)所以,我们将会这样做创建一个情节列表,然后将它们放在一起,就像它们被刻面一样。

library(tidyverse)
library(egg)

由于在实际数据中,hwy的平均值总是随着cyl的增加而单调递减,我们将为8柱Audis创建一个人为的高hwy值,仅用于说明:

mpg$hwy[mpg$manufacturer=="audi" & mpg$cyl==8] = 40

现在我们将数据拆分为manufacturer,这样我们就可以创建一个单独的图,因此每个制造商都有一个单独的cyl订单。我们将使用map函数来迭代制造商。

plot.list = split(mpg, mpg$manufacturer) %>% 
  map(function(dat) { 

    # Order cyl by mean(hwy)
    dat = dat %>% group_by(manufacturer, cyl) %>% 
      summarise(hwy = mean(hwy)) %>% 
      arrange(desc(hwy)) %>% 
      mutate(cyl = factor(cyl, levels=cyl))

    ggplot(dat, aes(cyl, hwy)) +
      geom_col() +
      facet_wrap(~ manufacturer) +
      theme(axis.title=element_blank()) +
      expand_limits(y=mpg %>% 
                      group_by(manufacturer,cyl) %>% 
                      mutate(hwy=mean(hwy)) %>% 
                      pull(hwy) %>% max)
  })

现在让我们删除y轴值并在我们将图表放在一起时不会出现在第一列中的图表中打勾:

num_cols = 5

plot.list[-seq(1,length(plot.list), num_cols)] =
  lapply(plot.list[-seq(1,length(plot.list), num_cols)], function(p) {
    p + theme(axis.text.y=element_blank(), 
              axis.ticks.y=element_blank())
  })

最后,我们列出了这些情节。来自ggarrange包的egg确保面板都具有相同的宽度(否则第一列中的面板将比其他面板更窄,因为y轴标签占据了空间)。

ggarrange(plots=plot.list, left="Highway MPG", bottom="Cylinders", ncol=num_cols)

请注意cyl的{​​{1}}值不是递增的顺序,表明我们的重新排序工作正常。

enter image description here

答案 1 :(得分:2)

这是一种不同的方法,可以使用here中的两个函数直接在ggplot中执行。我将使用eipi10的例子:

library(tidyverse)
mpg$hwy[mpg$manufacturer=="audi" & mpg$cyl==8] <- 40

dat <- mpg %>% group_by(manufacturer, cyl) %>% 
  summarise(hwy = mean(hwy)) %>% 
  arrange(desc(hwy)) %>% 
  mutate(cyl = factor(cyl, levels = cyl))

功能:

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}


scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}

情节:

ggplot(dat, aes(reorder_within(cyl, -hwy, manufacturer), y = hwy), hwy) + 
  geom_col() + 
  scale_x_reordered() +
  facet_wrap(~ manufacturer, scales = "free") +
  theme(axis.title=element_blank())

enter image description here

按升序排列:reorder_within(cyl, hwy, manufacturer)

没有功能的情节:

ggplot(dat, aes(cyl, y = hwy)) + 
  geom_col() + 
  facet_wrap(~ manufacturer, scales = "free") +
  theme(axis.title=element_blank())

enter image description here