如何显示组变量以及绘图轴上的数字中点?

How do I show a group variable along with the numeric mid point on the axis of my plot?

我有一些数据,这是其中的一个子集:

MyDataToSO <- data.frame(Age = c(2, 7, 12, 16, 21),
                     AgeGroup = c("0-4 years", "5-9 years", "10-14 years", "15-17 years", "18-24 years"),
                     Proportion = c(0.963, 0.965, 0.925, 0.701, 0.422))

我希望绘制数据,以便在 x 轴上得到相关 AgeGroup 显示在 Age 刻度线下方。 Age 值是 AgeGroup 类别的中点。

我有我想要的情节,除了在 x 轴的相关部分下添加 AgeGroup 波段:

ggplot(data = MyDataToSO, aes(x = Age, y = Proportion)) +
geom_point() +
geom_point(data = subset(MyDataToSO, Age %in% c(16,21)), color = "green")
scale_x_continuous(breaks=seq(0, 30, by = 10)) +
labs(x = "Age group", y = "Proportion")

图表有效,在正确的位置显示了相关的 Age,但没有迹象表明 Age 值来自年龄组。

我认为通过在 x 轴上添加第二个标签来显示这一点会很有用,这样生成的 x 轴看起来有点像:

|
|______________________________...
      |         |         |    ...
      2         7         12   ...
|__________|_________|_________|...
 "0-4 years  5-9 years  10-14 years"...

我需要稍微调整一下字体大小才能正常工作。我还想让年龄组线条比正常打印更亮(例如,不透明比正常少 25%)。我在年龄组标签周围加上了引号,以阻止 SO 将每个数字显示为橙色数字。

如何将此信息添加到我的图表中?我搜索了二级标签,但只找到了与二级轴相关的问题。如您所见,所需的分组信息存储在 AgeGroup 中,因此我“只”需要从那里提取相关值。

编辑:我加载了 ggh4x 包,ggplot 代码现在是这样的:

ggplot(data = MyDataToSO, aes(interaction(Age, AgeGroup), Proportion)) +
geom_point() +
geom_point(data = subset(MyDataToSO, Age %in% c(16,21)), color = "green")
scale_x_continuous(breaks=seq(0, 30, by = 10)) +
guides(x = "axis_nested") +
labs(x = "Age group", y = "Proportion")

但是它给出了一个错误,因为 x 轴是连续的。

编辑 2:绿点是插值。我现在有 17 到 20 岁的插值。但是这些重复相同的 AgeGroup 标签。这是个问题吗?

一种快速简便的方法是创建一个列表或变量,在其中附加 MyDataToSO$AgeMyDataToSO$AgeGroup 中的值,用两个回车符 returns 分隔(即 \n ).您将把 list/variable 传递给 scale_x_continuous 的 'labels' 指令。

library(tidyverse)

MyDataToSO <- tibble(Age = c(2, 7, 12, 16, 21),
                     AgeGroup = c("0-4 years", "5-9 years", "10-14 years", "15-17 years", "18-24 years"),
                     Proportion = c(0.963, 0.965, 0.925, 0.701, 0.422)) %>% 
 mutate(custom_labels = paste0(Age, "\n\n", AgeGroup)) ## This is where you create the custom labels

ggplot(data = MyDataToSO, aes(x = Age, y = Proportion)) +
    geom_point() +
    geom_point(data = subset(MyDataToSO, Age %in% c(16,21)), color = "green") + 
scale_x_continuous(breaks=seq(0, 30, by = 10)) +
    labs(x = "Age group", y = "Proportion") +
    scale_x_continuous(breaks = c(MyDataToSO$Age), ## Here you pass the relevant ages. Should be aligned with the custom_labels
                       labels = c(MyDataToSO$custom_labels)) ## Here you pass the custom label balues

另一种方法是添加注释,关闭裁剪,并在轴文本和轴标题之间添加更多 space,如下所示:

ggplot(data = MyDataToSO, aes(x = Age, y = Proportion)) +
  geom_point() +
  geom_point(data = subset(MyDataToSO, Age %in% c(16,21)), color = "green") +
scale_x_continuous(breaks=seq(0, 30, by = 10)) +
  labs(x = "Age group", y = "Proportion") +
  annotate("rect", fill = "gray80",
           xmin = c(0, 5, 10, 15, 18),
           xmax = c(5, 10, 15, 18, 24) - 0.2,
           ymin = 0.28, ymax = 0.32) +
  annotate("text", size = 3,
           x = MyDataToSO$Age + 0.5,
           y = 0.3, label = MyDataToSO$AgeGroup) +
  coord_cartesian(ylim = c(0.4, 1), clip = "off") +
  theme(axis.title.x = element_text(margin = margin(t = 25, r = 0, b = 0, l = 0)))

编辑:根据我对附加评论的理解,现在单独拆分 15:21。

MyDataToSO <- data.frame(Age = c(2, 7, 12, 15:21),
                         AgeGroup = c("0-4 years", "5-9 years", "10-14 years", 15:21),
                         Proportion = c(0.963, 0.965, 0.925, 0.701, .740, .677, .610, .540, .470, .401))


ggplot(data = MyDataToSO, aes(x = Age, y = Proportion)) +
  geom_point() +
  geom_point(data = subset(MyDataToSO, Age %in% c(16,21)), color = "green") +
  scale_x_continuous(breaks=seq(0, 30, by = 10)) +
  labs(x = "Age group", y = "Proportion") +
  annotate("rect", fill = "gray80",
           xmin = c(0, 5, 10, 15:21) - 0.4,
           xmax = c(5, 10, 15, 16:22) - 0.6,
           ymin = 0.28, ymax = 0.32) +
  annotate("text", size = 3,
           x = MyDataToSO$Age,
           y = 0.3, label = MyDataToSO$AgeGroup) +
  coord_cartesian(ylim = c(0.4, 1), clip = "off") +
  theme(axis.title.x = element_text(margin = margin(t = 25, r = 0, b = 0, l = 0)))

ggh4x 包有一个功能可以扩展 ggplot2 以更自动的方式执行此操作(https://cran.r-project.org/web/packages/ggh4x/vignettes/PositionGuides.html,向下滚动到“嵌套关系”)。