如何用两个 class 对 ggplot2 直方图进行分级,每个 class 具有独立的级别?

How to level a ggplot2 histogram with two classes, with independent levels for each class?

假设我有这个数据:

xy <- data.frame(cbind(c(1,2,3,4,5,2,3,4),c(rep('A',5),rep('B',3))))

所以,当我输入时

ggplot(xy, aes(x = x, fill = y)) +   
  geom_histogram(aes(y=..count../sum(..count..)), position = "dodge")

我得到这张图:

但我想看到独立水平的水平,即红色条水平为 0.2,蓝色条水平为 0.333。我怎样才能实现它?

此外,如何设置 y 轴以百分比而不是小数显示数字?

非常感谢。

这似乎可以解决问题。它使用 ..density.. 而不是 ..count..,这是一种相当丑陋的方法来计算 A/B 因子列中的水平数,然后使用 scales 包来获取 y 轴上的标签

ggplot(xy, aes(x = x, fill = y)) +
  geom_histogram(aes(y=..density../sum(..density..)*length(unique(xy$y)), group = y), position = "dodge") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1))

或者要计算 ggplot 中的所有内容,您可以先计算相对频率,然后使用此值将其与 geom_col 一起绘制。 preserve = "single" 保留等宽的条形:

library(ggplot2)
library(dpylr)

xy <- data.frame(x = c(1,2,3,4,5,2,3,4),
                 y = c(rep('A',5),rep('B',3)))

xy <- xy %>% 
  group_by(y, x) %>% 
  summarise(rel_freq = n()) %>% 
  mutate(rel_freq = rel_freq / n())

ggplot(xy, aes(x = x, y = rel_freq, fill = y)) +
  geom_col(position = position_dodge2(preserve = "single")) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1))