组合条形图与 R ggplot2:闪避和堆叠

combined barplots with R ggplot2: dodged and stacked

我有一个 table 的数据,其中已经包含几个值,这些值将被绘制在带有 ggplot2 包的条形图上(已经是累积数据)。

数据框中的数据 "reserves" 具有以下形式(简化):

period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15

第一列(周期)是地质时代。它将在 x 轴上,我不需要对其进行额外排序,因此我使用命令

准备了适当的因子标记
reserves$period <- factor(reserves$period, levels = reserves$period)

列 "amount" 是要绘制为 y 轴的主要列(它是每个时期中碳氢化合物的百分比,但也可以是绝对值,例如百万吨或其他) .所以基本情节由命令调用:

ggplot(reserves,aes(x=period,y=amount)) + geom_bar(stat="identity")

但问题来了。我需要在同一个条形图上绘制其他值,即 a1-a2、b1-b2 和 h1-h4。这些值是每个字母的百分比值(例如,a1=60,然后 a2=40;b1-b2 相同;对于 h1-h4,它们总计为 100。所以:我需要值 a1- a2 作为某种颜色,将 "amount" 条按比例划分为 x 的每个值(堆叠条形图),然后我需要相同的值 b1-b2;所以我们每个周期都有两个相邻的列(分组条形图),每个它们中的一个是堆叠的。接下来,我需要第三列,对于值 h1-h4,也许,也作为堆叠条形图,但要么作为第三列,要么作为第一列上方的交错条形图。

因此布局如下所示:

我知道我需要先用包 reshape2 重塑数据,然后在 geom_bar() 中使用选项 position="dodge" 或 position="fill",但这里是它们的组合。第三个条形图(对于值 h1-h4)似乎需要 "stacked percent" 具有固定高度的表示。

是否有以更直观的方式处理绘图数据的包?比方说,我们只是声明,我们想要绘制变量 ai、bi、hi。

首先,您应该将数据从宽变长,然后将您的比例缩放到它们的原始值。然后将您的旧列名称(现在 "lett" 级别)拆分为字母和数字以进行标记。如果您的真实数据不是这样格式化的 (a1...h4),也有办法处理它。

library(dplyr)
library(tidyr)
library(ggplot2)

reserves <- read.csv(text = "period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15") 

reserves.tidied <- reserves %>% 
  gather(key = lett, value = prop, -period, -amount) %>% 
  mutate(rawvalue = prop * amount/100,
         lett1 = substr(lett, 1, 1),
         num = substr(lett, 2, 2)) 

reserves.tidied
   period amount lett prop rawvalue lett1 num
1       J   18.1   a1   30    5.430     a   1
2       K   29.0   a1   65   18.850     a   1
3       P   13.3   a1   94   12.502     a   1
4       N   21.6   a1   95   20.520     a   1
5       J   18.1   a2   60   10.860     a   2
6       K   29.0   a2   35   10.150     a   2
7       P   13.3   a2    6    0.798     a   2
8       N   21.6   a2    5    1.080     a   2
9       J   18.1   b1   40    7.240     b   1
10      K   29.0   b1   75   21.750     b   1
11      P   13.3   b1   85   11.305     b   1
12      N   21.6   b1   80   17.280     b   1
13      J   18.1   b2   60   10.860     b   2
14      K   29.0   b2   25    7.250     b   2
15      P   13.3   b2   15    1.995     b   2
16      N   21.6   b2   20    4.320     b   2
17      J   18.1   h1   15    2.715     h   1
18      K   29.0   h1    5    1.450     h   1
19      P   13.3   h1   10    1.330     h   1
20      N   21.6   h1   10    2.160     h   1
21      J   18.1   h2   50    9.050     h   2
22      K   29.0   h2   50   14.500     h   2
23      P   13.3   h2   55    7.315     h   2
24      N   21.6   h2   55   11.880     h   2
25      J   18.1   h3   30    5.430     h   3
26      K   29.0   h3   40   11.600     h   3
27      P   13.3   h3   20    2.660     h   3
28      N   21.6   h3   20    4.320     h   3
29      J   18.1   h4    5    0.905     h   4
30      K   29.0   h4    5    1.450     h   4
31      P   13.3   h4   15    1.995     h   4
32      N   21.6   h4   15    3.240     h   4

然后绘制整理后的数据,您需要横跨 x 轴的字母,以及我们刚刚用 amount*proportion 在 y 轴上计算的原始值。我们将 geom_col 从 1 堆叠到 2 或从 1 堆叠到 4(reverse=T 参数覆盖默认值,默认值将在堆栈底部有 2 或 4)。 alphafill 让我们区分同一柱中的组和柱之间的组。

然后 geom_text 用名称、换行符和原始百分比标记每个堆叠的段,以每个段为中心。 scale 再次反转默认行为,使每个栏中的 1 最暗,2 或 4 最亮。然后你 facet 穿过,为每个周期制作一组柱状图。

  ggplot(reserves.tidied, 
         aes(x = lett1, y = rawvalue, alpha = num, fill = lett1)) +
    geom_col(position = position_stack(reverse = T), colour = "black") +
    geom_text(position = position_stack(reverse = T, vjust = .5), 
              aes(label = paste0(lett, ":\n", prop, "%")), alpha = 1) +
    scale_alpha_discrete(range = c(1, .1)) +
    facet_grid(~period) +
    guides(fill = F, alpha = F) 

重新排列它,使 "h" 条不同于 "a" 和 "b" 条有点复杂,您必须考虑您想要的方式呈现,但它是完全可行的。