这可以通过使用dplyr 稍微处理您的数据然后将stat 更改为"identity" 来实现。
我正在使用您提供的样本中的这些数据:
df <- structure(list(group = c("A", "C", "A", "A", "C", "A", "B", "A",
"C", "B", "A", "A", "C"), IntervalDays = c("[0,5]", "(5,10]",
"(5,10]", "[0,5]", "(5,10]", "[0,5]", "(5,10]", "(5,10]", "(5,10]",
"(5,10]", "[0,5]", "[0,5]", "[0,5]")), row.names = c(NA, -13L
), class = "data.frame")
当应用于df 时,您的绘图代码给出了下图(到目前为止,我从您的原始绘图代码中唯一更改的是geom_histogram 到geom_bar,因为这对您的数据类型更有意义):
library(ggplot2)
# original plot code, changed to geom_bar
ggplot(df, aes(x = IntervalDays, fill = group)) +
geom_bar(stat = "count") +
geom_label(stat = "count", aes(label = round(..prop..*100, digits = 1),
group = c(group)),
position = position_stack(vjust = 0.5))
我们不希望这样做,因为它计算的是组的比例,而不是列的比例。为了获得列比例,我使用了dplyr,如下所示:
library(dplyr)
df_new <- df %>% group_by(group, IntervalDays) %>%
summarise(sum = n()) %>% group_by(IntervalDays) %>%
mutate(col_prop = sum/sum(sum))
> df_new
# A tibble: 5 x 4
# Groups: IntervalDays [2]
group IntervalDays sum col_prop
<chr> <chr> <int> <dbl>
1 A (5,10] 2 0.286
2 A [0,5] 5 0.833
3 B (5,10] 2 0.286
4 C (5,10] 3 0.429
5 C [0,5] 1 0.167
然后我使用尽可能多的原始代码绘制new_df。主要区别是我已将stat 从"count" 更改为"identity",以便明确绘制sum 中的值。由于我们自己计算了col_prop,这就是我分配给label 参数的值:
ggplot(df_new, aes(x = IntervalDays, y = sum, fill = group)) +
geom_bar(stat = "identity") +
geom_label(stat = "identity", aes(label = round(col_prop*100, digits = 1),
group = group),
position = position_stack(vjust = 0.5))
在计算原始比例时,您可以了解ggplot 在幕后所做的精髓。是这样的,没有我们上面看到的第二个group_by:
df %>% group_by(group, IntervalDays) %>%
summarise(sum = n()) %>%
mutate(col_prop = sum/sum(sum))
# A tibble: 5 x 4
# Groups: group [3]
group IntervalDays sum col_prop
<chr> <chr> <int> <dbl>
1 A (5,10] 2 0.286
2 A [0,5] 5 0.714
3 B (5,10] 2 1
4 C (5,10] 3 0.75
5 C [0,5] 1 0.25