如何在 ggplot geom_point 中实现轴条目的特定方面排序?

How to achieve a facet specific ordering of axis entries in ggplot geom_point?

我考虑以下类型的 geom_point 情节。我需要为每个垂直方面 s 实现 m 上条目的排序,根据它们的大小 v。下图中所需的顺序是 s1 A、C、B、D 和 s2 B、A、C(或 B、C、A)。困难在于,虽然我可以通过重新排列因子水平来指定一般顺序 m,但我不知道如何为每个方面更改此顺序。

set.seed(1)
m1 = c('A','B','C','D')
m2 = c('A','B','C')
s = c(rep('s1',4),rep('s2',3))
d = data.frame(m = factor(c(m1,m2)), s=factor(s), v=sample(1:10, replace=T,7))

library(ggplot2)
ggplot(d, aes(x=m, y=v)) + geom_point(size=2) + coord_flip() + 
  facet_grid( s~. , scales='free', space='free')

一个选择是确实使用您所描述的因子水平,但使用一个前缀来分隔不同方面的水平。稍后,您可以使用 scale 的 labels 参数删除前缀。示例如下:

set.seed(1)
m1 = c('1A','1B','1C','1D')
m2 = c('2A','2B','2C')
s = c(rep('s1',4),rep('s2',3))
d = data.frame(m = c(m1,m2), 
               s=factor(s), 
               v=sample(1:10, replace=T,7),
               stringsAsFactors = FALSE)
d$m <- factor(d$m, levels = c("1A", "1C", "1B", "1D", "2B", "2A", "2C"))

library(ggplot2)
ggplot(d, aes(x=m, y=v)) + 
  geom_point(size=2) + 
  coord_flip() + 
  facet_grid( s~. , scales='free', space='free') +
  scale_x_discrete(
    labels = function(x){substr(x, 2, nchar(x))}
  )

这类似于 teunbrand 的回答,除了它使用 forcats 在每个方面自动分配正确的顺序(从低到高),而无需提前指定:

library(dplyr)
library(ggplot2)

d %>% mutate(plot_fct = forcats::fct_cross(s,  m)) %>%
      mutate(plot_fct = forcats::fct_reorder(plot_fct, -v)) %>%
      ggplot(aes(x=plot_fct, y=v)) + geom_point(size=2) + 
        facet_grid( s~. , scales='free', space='free') +
        scale_x_discrete(labels = function(x) substr(x, 4, 5)) +
        coord_flip() + labs(x = "m")