R语言 使用ggplot定义堆叠条的不同起点

3pmvbmvn  于 2023-09-27  发布在  其他
关注(0)|答案(1)|浏览(80)

我试图做一个堆叠条形图,但每个酒吧应该开始在最后一个酒吧的最高点。我可以手动为每个条形图添加起始点,但我不知道在ggplot中何处指定。
这是画框和情节

df <- data.frame(Name = c("A", "A", "A", "B", "B", "B", "C", "C", "C"), category = rep(1:3, times=3), value = c(5, 8, 4, 3, 1, 8, 5, 11, 3), difference_value = c(5, 3, -4, 3, -2, 7, 5, 6, -8))

ggplot(df, aes(fill=reorder(Name, difference_value), y=difference_value, x=category)) +
  geom_bar(position="stack", stat="identity")

现在,类别1的第一个条应该从0开始,但后续的条应该从最后一个类别的条的末尾开始:在这种情况下,类别2的柱应该从13开始,B的堆叠部分应该向下,因为它是负的,而A和C的值向上,因为它们是正的。
应该是这样的:

多谢了!

vs91vp4v

vs91vp4v1#

geom_bargeom_col始终从0开始,即你不能设定起始位置。相反,你可以使用geom_rect来实现你想要的结果,但是需要一些努力来计算每个酒吧的开始和结束位置:

library(ggplot2)
library(dplyr, warn = FALSE)

df <- df |>
  # Indicator for bars going down
  mutate(is_down = difference_value < 0) |>
  # Arrange dataset
  arrange(category, is_down, abs(difference_value)) |>
  # Total of bars going up
  mutate(
    total_pos = sum(difference_value[!is_down]),
    .by = category
  ) |>
  # Compute start and end of each bar
  mutate(
    ymax = cumsum(difference_value),
    ymin = lag(ymax, default = 0),
    xmin = category - .45,
    xmax = category + .45,
    .by = c(is_down, category)
  ) |>
  # Shift start and end upwards by the value of the prevoius bar
  mutate(
    across(c(ymin, ymax), ~ .x + lag(cumsum(total_pos), default = 0)),
    .by = Name
  )

ggplot(df, aes(
  fill = reorder(Name, difference_value)
)) +
  geom_rect(
    aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)
  )

相关问题