Facet_wrap:Y 比例从 0 到 1,基于绘制的变量

Facet_wrap: Y scale from 0 to 1, based on variable plotted

有没有办法根据绘制的变量,在我的例子中(见下文)性别,将 facet wrap 中的 y 轴从 0 缩放到 1?就好像 ..count.. / max(..count..) 会在 gender 变量上分组一样。任何想法将不胜感激。

以下是我目前的尝试

ex[c("var1","var2", "gender")] %>%
  gather(-gender, key="var", value = "value") %>% 
  ggplot(aes(value, fill = gender)) +  geom_histogram(aes(y=..count.. / max(..count..)), stat="count") + 
  facet_wrap(~var + gender, scales = "free_x", ncol= 2)  +
  ylab("% in each group") 

导致

数据样本:

structure(list(row = 1:100, var1 = c(" <25", " <25", " 25-50", 
" 25-50", " 50-75", " <25", " 25-50", " 25-50", " 25-50", " 25-50", 
" 50-75", " 25-50", " 25-50", " 25-50", " <25", " 25-50", " 25-50", 
" 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", 
">75", " 25-50", " 25-50", " <25", " <25", " 25-50", " 25-50", 
" 25-50", " 50-75", " 50-75", " 25-50", " 25-50", " 50-75", " 25-50", 
" 25-50", " <25", " 25-50", " 25-50", " 25-50", " 25-50", " <25", 
" 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", 
" 25-50", " 50-75", " 50-75", " <25", " 25-50", " <25", " 50-75", 
" <25", " <25", " <25", " 25-50", " <25", " <25", " 25-50", " 50-75", 
" 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " <25", " 25-50", 
" <25", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " <25", 
" 50-75", " 25-50", " 25-50", " 25-50", " 25-50", " 25-50", " 50-75", 
" 25-50", " <25", " 25-50", " 25-50", " <25", " 25-50", " <25", 
" <25", " 25-50", " 25-50", " <25", " <25"), var2 = c(0L, 0L, 
0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 
0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 
1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L), gender = c("M", "M", "M", "M", "M", "M", "M", "F", "M", 
"M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", 
"M", "M", "F", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", 
"M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", 
"M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", 
"M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", 
"M", "M", "M", "M", "F", "M", "M", "M", "M", "M", "M", "M", "M", 
"F", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M"
)), class = "data.frame", row.names = c(NA, -100L))

据我所知,没有 out-of-the-box 解决方案可以告诉 facet_wrap 进行您想要实现的那种规范化。相反,您必须手动执行此操作。

有(至少)两种方法可以实现这一点:

  1. 简单的方法是 pre-compute(规范化)计数并利用 geom_col
  2. 更复杂的方法是使用例如tapply 通过 gender 计算最大计数。对于这种方法,我建议切换到 geom_bar 而不是使用 geom_histogram.

两种方法如下所示:

library(ggplot2)
library(tidyr)
library(dplyr)

ex[c("var1","var2", "gender")] %>%
  gather(-gender, key="var", value = "value") %>% 
  count(gender, var, value) %>% 
  group_by(gender) %>% 
  mutate(pct = n / max(n)) %>% 
  ggplot(aes(value, pct, fill = gender)) +  
  geom_col() +
  facet_wrap(~var + gender, scales = "free_x", ncol= 2)  +
  ylab("% in each group") 

ex[c("var1","var2", "gender")] %>%
  gather(-gender, key="var", value = "value") %>% 
  ggplot(aes(value, fill = gender)) +  
  geom_bar(aes(y = ..count.. / tapply(..count.., ..fill.., function(x) max(x))[..fill..]), stat="count") + 
  facet_wrap(~var + gender, scales = "free_x", ncol= 2)  +
  ylab("% in each group")