直方图中 ggplot 中 bin 的 r 百分比

r percentage by bin in histogram ggplot

我有这样的数据集 ->

library(ggplot2)

response <- c("Yes","No")
gend <- c("Female","Male")

purchase <- sample(response, 20, replace = TRUE)
gender <- sample(gend, 20, replace = TRUE)

df <- as.data.frame(purchase)
df <- cbind(df,gender)

所以 head(df) 看起来像这样 ->

  purchase gender
1      Yes Female
2       No   Male
3       No Female
4       No Female
5      Yes Female
6       No Female

此外,您可以验证我的示例,这里是 table(df) 我的特定抽样。
(请不要担心匹配我的百分比)

         gender
purchase Female Male
     No       6    3
     Yes      4    7

我想要 "histogram" 显示性别,但按购买分开。 我已经走了这么远 ->

ggplot(df) + 
       geom_bar(aes(y = (..count..)/sum(..count..)),position = "dodge") + 
       aes(gender, fill = purchase)

生成 ->

带拆分箱的直方图,按百分比,但不是我想要的聚合水平

Y 轴有我想要的百分比,但它有图表的每个条形图占整个图表的百分比。 我想要的是两个 "Female" 柱,每个柱都是各自 "Purchase" 的百分比。所以在上面的图表中,我希望有四个柱状图, 66%, 36%, 33%, 64% , 以该顺序。

我试过 geom_histogram 无济于事。我检查了 SO、搜索、ggplot 文档和几本书。

关于看之前关于facets的问题的建议;这确实有效,但我希望保持图表在视觉上与上面一样,而不是分成 "two charts"。所以...

有人知道怎么做吗?

谢谢。

尝试这样的事情:

library(tidyverse)

df %>% 
count(purchase, gender) %>% 
ungroup %>% 
group_by(gender) %>% 
mutate(prop = prop.table(n)) %>% 
ggplot(aes(gender, prop, group = purchase)) + 
geom_bar(aes(fill = purchase), stat = "identity", position = "dodge")

前 5 行创建了一个列 prop(对于 "proportion"),它聚合了 gender

要到达那里,您首先 count 每个 purchase 通过 gender(类似于 table(df) 的输出)。取消分组然后仅通过 gender 重新分组给出我们想要的聚合。

关于你想要的百分比,分母是基于性别,还是购买?在上面给出的示例中,66% 的女性未购买将是 6 除以未购买的总和 (6+3) 而不是所有女性的总和 (6+4)。

绝对可以绘制它,但我不确定结果是否可以直观地解释。我一时糊涂了。

以下技巧利用了 weight 美学。我在这里根据问题中描述的预期输出使用 purchase 作为分组变量,尽管我认为性别更有意义(根据上面的 TTNK ):

df <- data.frame(purchase = c(rep("No", 6), rep("Yes", 4), rep("No", 3), rep("Yes", 7)),
                 gender = c(rep("Female", 10), rep("Male", 10)))

ggplot(df %>% 
         group_by(purchase) %>% #change this to gender if that's the intended denominator
         mutate(w = 1/n()) %>% ungroup()) + 
  aes(gender, fill = purchase, weight = w)+ 
  geom_bar(aes(x = gender, fill = purchase), position = "dodge")+
  scale_y_continuous(name = "percent", labels = scales::percent)