【问题标题】:R: reorder factor levels for several individual plotsR:对几个单独的图重新排序因子水平
【发布时间】:2018-05-14 08:34:51
【问题描述】:

我正在尝试从同一个 data.frame 创建几个单独的图,每个图的 y 轴上的因子水平顺序不同。每个图都应该对 y 上的因子水平进行递减排序。

我知道这可以为每个情节手动完成,但我正在寻找一种更有效和优雅的方式,因为我需要创建大量的情节。这不一定包括使用 facet_wrap,如果有另一种方法,可能是循环等?

library(ggplot2)
library(dplyr)
data("diamonds")

获取数据集并按两个因子水平(清晰度和切割)聚合:

means <- diamonds %>%
group_by(clarity, cut) %>%
summarise(carat = mean(carat))

在这里,我通过一个因素重新排序,但最终我想为每个图单独重新排序(通过降低清晰度的平均值)。

means$clarity <- reorder(means$clarity, means$carat, FUN = mean)

使用 face_wrap 创建单独的图。使用 coord_flip 可以更轻松地比较绘图。

ggplot(means, aes(x = clarity, y = carat)) +
  geom_col() +
  facet_wrap(~cut, ncol = 1) +
  coord_flip()

您会看到,这会为每种切割类型创建单独的图,但 y 轴上的因子水平顺序对于每种情况都不正确。我怎样才能正确地订购它们,而不必为每种类型的切割手动执行?

【问题讨论】:

  • 显然不完全是您想要的,但由于您要求一个优雅的解决方案,我只能考虑编写一个创建单个图的函数(使用ggplot(means, aes(x = reorder(clarity, carat), y = carat))lapply 通过方面然后使用gridExtra 重新组合单个图。它只会在您的代码中添加几行。

标签: r ggplot2 dplyr


【解决方案1】:

这可以通过利用两个函数在一个图中完成:

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), ...)
}

可在 github dgrtwo/drlib 上获得

ggplot(means, aes(x = reorder_within(clarity, carat, cut, mean), y = carat)) + 
  geom_col() + 
  scale_x_reordered() +
  facet_wrap(~cut,  scales = "free_y", ncol = 1) +
  coord_flip()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    相关资源
    最近更新 更多