Я не знаю, как это автоматизировать, возможно, проще всего рассчитать пропорции и суммы вне графика.
Проще переупорядочить классы вне графика, чтобы ваш текст мог брать уровни факторов.
df$x <- reorder(df$classes, -df$quantity)
Далее вы можете рассчитать статистику, которую вы хотите. Ниже я предположил, что если мы разделим df
по классам, это всегда будет порядок flag = 0
, flag = 1
, поэтому мы можем взять x[2]/x[1]
как пропорцию.
text_df <- data.frame(
class = sapply(split(df$classes, df$classes), unique),
sum = sapply(split(df$quantity, df$classes), sum),
prop = sapply(split(df$quantity, df$classes), function(x){x[2]/(x[1]+x[2])})
)
Тогда мы позволим text_df$class
принять тот же порядок, что и df$x
.
text_df$class <- factor(text_df$class, levels = levels(df$x))
Затем мы сделаем график похожим на ваш пример, помните, что мы переупорядочили переменную x ранее:
ggplot(df, aes(x = x, y = quantity)) +
geom_bar(aes(fill = as.factor(flag)), stat="identity") +
theme(axis.text.x=element_text(angle = 90, hjust = 1)) +
labs(x = NULL, y = "Quantity", fill = "flag") +
scale_fill_manual(values=c("firebrick","dodgerblue4"),
labels=c("1"="Yes","0"="No"))+
theme(axis.ticks = element_blank())
И добавьте два geoms для текста, один для пропорции, один для суммы; оба со смещением по оси Y.
+geom_text(data = text_df,
aes(x = class,
y = sum + 100, # some offset
label = sum)) +
geom_text(data = text_df,
aes(x = class,
y = sum - 100, # opposite offset
label = scales::percent(prop)))
И я думаю, что сработало. Удачи!