我正在使用以下数据制作堆积条形图:
dput(head(Intensity_data))
structure(list(Weekday = structure(c(1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L,
6L, 6L, 7L, 7L, 7L, 7L), levels = c("Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday"), class = c("ordered",
"factor")), Activity_Level = structure(c(1L, 2L, 3L, 4L, 1L,
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L,
2L, 3L, 4L, 1L, 2L, 3L, 4L), levels = c("mean_very_active", "mean_fairly_active",
"mean_lightly_active", "mean_sedentary"), class = "factor"),
Mean_Minutes = c(20, 15, 174, 990, 23, 14, 192, 1028, 23,
14, 197, 1007, 21, 13, 190, 989, 19, 12, 185, 962, 20, 12,
204, 1000, 22, 15, 207, 964)), row.names = c(NA, -28L), class = c("tbl_df",
"tbl", "data.frame"))
我的目标是创建一个堆积条形图,显示每个工作日执行每个活动级别所花费的分钟数,并在每个条形顶部带有每个级别的标签和总和值。到目前为止,我只能做到部分。
ggplot(Intensity_data, aes(x=Weekday,
y=Mean_Minutes,
fill=Activity_Level
)
)+
geom_col()+
labs(title="Activity Level per Weekday",
x=NULL,
y="Minutes")+
guides(fill=guide_legend(title="Activity Level"))+
scale_fill_discrete(labels=c("Very Active",
"Fairly Active",
"Lightly Active",
"Sedentary")
)+
geom_text(aes(label=Mean_Minutes),
size=3,
hjust=0.5,
vjust=2,
position="stack"
)
但是,正如您所看到的,顶部的部分太短,因此标签被挤在一起。因此,我只想添加 100 以上的数据值的标签,并在每个条形的顶部添加总和标签。
为了执行前者,我尝试在 geom_text 层中使用 ifelse,但我不清楚应该如何编写它而不引发错误。这是我最新的尝试。
geom_text(aes(label=ifelse(Mean_Minutes<100, NA)
),
size=3,
hjust=0.5,
vjust=2
)
为了在每个条的顶部添加总和标签,我尝试使用相应的值创建一个新的数据框并添加另一层 geom_text 但它没有成功。我认为一定有一种更简单的方法可以做到这一点,但我不再有任何线索了。过去 4 小时一直在尝试此操作,但没有结果。
感谢任何建议或指导。
编辑:我无法以正确的方式发布图像,因为我是新人并且没有足够的声誉点
谢谢!!
为了使条件标签按预期工作,一个条件应返回您想要打印的值 (
Mean_Minutes
)。 ifelse(Mean_Minutes>100, Mean_Minutes, ''))
设置标签美观以显示 Mean_Minutes
的值(如果大于 100),否则显示空字符串。
有几种方法可以添加每列的总计,包括创建汇总数据框。我选择使用内置的汇总函数来计算它。
library(ggplot2)
df |>
ggplot(aes(x=Weekday,
y=Mean_Minutes,
fill=Activity_Level
)
)+
geom_col() +
labs(title="Activity Level per Weekday",
x=NULL,
y="Minutes")+
guides(fill=guide_legend(title="Activity Level"))+
scale_fill_discrete(labels=c("Very Active",
"Fairly Active",
"Lightly Active",
"Sedentary")
)+
# label bars where Mean_Minutes is greater than 100
geom_text(aes(label=ifelse(Mean_Minutes>100, Mean_Minutes, '')),
size=3,
hjust=0.5,
position= position_stack(vjust = 0.5)
) +
# Annotate each bar with the sum of all activity levels
geom_text(aes(label = after_stat(y), group = Weekday),
stat = 'summary', fun = sum, vjust = -1) +
# Extend y-axis so totals aren't clipped
scale_y_continuous(expand = expansion(mult = c(0,0.06)))