如何在条形图顶部添加计数,以及条形图内的填充百分比?
How to add counts on top of bars, and percentage of fill inside bars?
我有一些数据,其中每个观察包含 2 个因素,类(A 和 E 之间的字母)和标志(0 或 1)。在应用 group_by(类,flag) 和 summarize(frequency=n()) 之后,我得到了一个类似于这个的数据框:
classes <-as.factor(c("A", "A", "B", "B", "C", "C", "D", "D", "E", "E"))
flag <- as.factor(rep(c(0,1),10))
quantity <- c(856, 569, 463, 125, 795, 313, 1000, 457, 669, 201)
df <- data.frame(classes, flag, quantity)
我设法得到了我想要的图表(有序的柱状图,每个 类 的水平一个柱状图,每个柱状图填充了标志的比例)用这个代码:
ggplot(df, aes(x = reorder(classes, -quantity), 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())
但是,我不确定如何使用 geom_text() 来包含每个柱顶部的总计数以及柱内填充值的比例。
感谢您的帮助!
我不知道如何自动执行此操作,可能最简单的方法是在绘图之外计算比例和总和。
在图外重新排序 类 更容易,这样您的文本就可以接管因子水平。
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())
并为文本添加两个geom,一个为比例,一个为总和;都带有 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)))
而且我认为成功了。祝你好运!
我有一些数据,其中每个观察包含 2 个因素,类(A 和 E 之间的字母)和标志(0 或 1)。在应用 group_by(类,flag) 和 summarize(frequency=n()) 之后,我得到了一个类似于这个的数据框:
classes <-as.factor(c("A", "A", "B", "B", "C", "C", "D", "D", "E", "E"))
flag <- as.factor(rep(c(0,1),10))
quantity <- c(856, 569, 463, 125, 795, 313, 1000, 457, 669, 201)
df <- data.frame(classes, flag, quantity)
我设法得到了我想要的图表(有序的柱状图,每个 类 的水平一个柱状图,每个柱状图填充了标志的比例)用这个代码:
ggplot(df, aes(x = reorder(classes, -quantity), 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())
但是,我不确定如何使用 geom_text() 来包含每个柱顶部的总计数以及柱内填充值的比例。
感谢您的帮助!
我不知道如何自动执行此操作,可能最简单的方法是在绘图之外计算比例和总和。
在图外重新排序 类 更容易,这样您的文本就可以接管因子水平。
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())
并为文本添加两个geom,一个为比例,一个为总和;都带有 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)))
而且我认为成功了。祝你好运!