带有三个级别的背对背条形图:我可以将绘图居中吗?

时间:2019-06-11 11:36:11

标签: r ggplot2

我希望创建一个背对背的条形图。在我的数据中,我有多个2017年和2018年的物种观测值(n)。有些物种仅在2017年发生,另一些物种在两年内发生,有些仅在2018年发生。我希望以围绕物种数的图表形式对此进行描述在多个站点(a,b,c)都发生了两年。

首先,我创建一个数据集:

n <- sample(1:50, 9)
reg <- c(rep("2017", 3), rep("Both",3), rep("2018", 3))
plot <- c(rep(c("a", "b", "c"), 3))

d4 <- data.frame(n, reg, plot)

我使用ggplot尝试绘制图形-我尝试了两种方法:

library(ggplot2)
ggplot(d4, aes(plot, n, fill = reg)) +
  geom_col() +
  coord_flip()

ggplot(d4, aes(x = plot, y = n, fill = reg))+
  coord_flip()+
  geom_bar(stat = "identity", width = 0.75)

我得到与我想要的情节相似的情节。但是,希望蓝色的“两个”柱位于2017年和2018年柱之间。此外,我的主要问题是,我想将“两个”栏居中。 2017列应扩展到左侧,而2018列应扩展到右侧。我的问题有点类似于下面的链接。但是,由于图形中只有三个级别而不是四个级别,因此无法使用以下相同的方法。

Creating a stacked bar chart centered on zero using ggplot

1 个答案:

答案 0 :(得分:1)

我不确定这是最好的方法,但是这是一种方法:

library(dplyr)
d4pos <- d4 %>%
    filter(reg != 2018) %>%
    group_by(reg, plot) %>%
    summarise(total = sum(n)) %>% 
    ungroup() %>%
    mutate(total = total * ifelse(reg == "Both", .5, 1))
d4neg <- d4 %>%
    filter(reg != 2017) %>%
    group_by(reg, plot) %>%
    summarise(total = - sum(n)) %>% 
    ungroup() %>%
    mutate(total = total * ifelse(reg == "Both", .5, 1))

ggplot(data = d4pos, aes(x = plot, y = total, fill = reg)) + 
    geom_bar(stat = "identity") + 
    geom_bar(data = d4neg, stat = "identity", aes(x = plot, y = total, fill = reg)) + 
    coord_flip()

我为每个组的总数生成两个数据帧。一个包含2017和两者的一半,另一个包含其余。翻转了2018数据框的值以绘制在负侧。

输出看起来像这样:

enter image description here

编辑 如果要在水平轴的两个方向上都具有正值,则可以执行以下操作:

ggplot(data = d4pos, aes(x = plot, y = total, fill = reg)) + 
    geom_bar(stat = "identity") + 
    geom_bar(data = d4neg, stat = "identity", aes(x = plot, y = total, fill = reg)) + 
    scale_y_continuous(breaks = seq(-50, 50, by = 25), 
                       labels = abs(seq(-50, 50, by = 25))) +
    coord_flip()