如何在金字塔图表中使 expand_limits 动态化?

How to make expand_limits dynamic in a pyramid chart?

我想制作一个人口金字塔图来显示我拥有的 DF 中不同工作的年龄和性别差异(下面的小样本)。我想自动制作所有图表,而不必手动更改代码,因为这对我原来的 DF 中的所有作业来说都非常耗时。在 ggplot 中制作金字塔图很难但有可能,但我不知道如何完全自动化。我有两个问题

  1. 目前我需要手动设置扩展限制。在某些工作中,男性较多,而在某些工作中,女性较多。即使我为所有作业(大的和小的)保留相同的 y 轴长度,我也需要手动更改 expand_limits 中的 -/+。我可以以某种方式使其自动化或同时给出扩展限制 -15000 和 15000 吗?害怕现在我只操纵一个轴。 (expand_limits(y=-15000).

  2. A Bonus but problem,如果我们能解决它就太好了,但这不是必须的。是否可以使 y 轴长度和 expand_limits 动态,以便它适合大小作业。例如:

建设者

expand_limits(y=-15000)+ 
  scale_y_continuous(breaks =c(-15000,-7500,0,7500,15000),
                      label =c(15000,7500,0,7500,15000))+

公务员

expand_limits(y=-500)+ 
  scale_y_continuous(breaks =c(-500,-250,0,250,500),
                      label =c(500,250,0,250,500))+

非常感谢任何帮助

示例 DF

Job           Age     Gender     People
Builder       25-34    M          12752
Builder       25-34    F          386
Builder       35-44    M          13980
Builder       35-44    F          390
Builder       45-54    M          9686
Builder       45-54    F          361
Builder       55-64    M          4924
Builder       55-64    F          334
Builder       65+      M          961
Builder       65+      F          69
Builder       Under 25 M          4639
Builder       Under 25 F          200
Civil servant 25-34    M          88
Civil servant 25-34    F          274
Civil servant 35-44    M          58
Civil servant 35-44    F          464
Civil servant 45-54    M          45
Civil servant 45-54    F          523
Civil servant 55-64    M          43
Civil servant 55-64    F          234
Civil servant 65+      M          12
Civil servant 65+      F          121
Civil servant Under 25 M          21
Civil servant Under 25 F          76

我的代码

Pyramid <-Pyramid %>%
  filter(Job == "Builder") #"Civil servant" for other job in the example.

Pyramid$People <- ifelse(Pyramid$Gender == "M",Pyramid$People*-1, Pyramid$People)

Pyramid$Age <- fct_relevel(Pyramid$Age, "Under 25","25-34","35-44","45-54","55-64","65+")

ggplot(Pyramid ,aes(x=Age, y=People, fill=Gender))+
  geom_bar(data = subset(Pyramid, Gender =="F"), stat = "identity")+
  geom_bar(data = subset(Pyramid, Gender =="M"), stat = "identity")+
  coord_flip()+
  theme_minimal(base_size = 17)+
  scale_fill_manual(values = c("M" = "#0071ce",
                               "F" = "#d30031"),
                    name=" ",
                    labels=c("Men","Women"))+ 
  expand_limits(y=-15000)+  #This is the problem line for me
  scale_y_continuous(breaks =c(-15000,-7500,0,7500,15000), #And these two lines as well
                      label =c(15000,7500,0,7500,15000))+
  ylab(NULL)+
  theme(legend.position = "bottom",
        axis.title.y=element_blank())

这就是我想要的,对于不同的工作,扩展限制需要不同 +/-

这是删除了 expand_limits

Expand_limits 以性别为中心

试试这个:

library(tidyverse)

Pyramid <- tribble(
  ~Job, ~Age, ~Gender, ~People,
  "Builder", "25-34", "M", 12752,
  "Builder", "25-34", "F", 386,
  "Builder", "35-44", "M", 13980,
  "Builder", "35-44", "F", 390,
  "Builder", "45-54", "M", 9686,
  "Builder", "45-54", "F", 361,
  "Builder", "55-64", "M", 4924,
  "Builder", "55-64", "F", 334,
  "Builder", "65+", "M", 961,
  "Builder", "65+ ", "F", 69,
  "Builder", "Under 25", "M", 4639,
  "Builder", "Under 25", "F", 200,
  "Civil servant", "25-34", "M", 88,
  "Civil servant", "25-34", "F", 274,
  "Civil servant", "35-44", "M", 58,
  "Civil servant", "35-44", "F", 464,
  "Civil servant", "45-54", "M", 45,
  "Civil servant", "45-54", "F", 523,
  "Civil servant", "55-64", "M", 43,
  "Civil servant", "55-64", "F", 234,
  "Civil servant", "65+", "M", 12,
  "Civil servant", "65+", "F", 121,
  "Civil servant", "Under 25", "M", 21,
  "Civil servant", "Under 25", "F", 76
)

data_df <- Pyramid %>%
  filter(Job == "Builder") %>%
  mutate(
    People = if_else(Gender == "M", People * -1, People),
    Age = factor(Age, levels = c("Under 25", "25-34", "35-44", "45-54", "55-64", "65+"))
  ) 

max <- max(abs(data_df$People))
min <- max * -1

data_df %>%
  ggplot(aes(Age, People, fill = Gender)) +
  geom_col() +
  coord_flip() +
  theme_minimal(base_size = 17) +
  scale_fill_manual(values = c("#d30031", "#0071ce")) +
  scale_y_continuous(limits = c(min, max)) +
  labs(y = NULL, fill = NULL) +
  theme(legend.position = "bottom")

reprex package (v2.0.1)

于 2022-05-07 创建