在ggplot2中,如何将堆积直方图中的小值条组合在一起?

时间:2016-12-22 01:44:43

标签: r ggplot2

示例数据:

tmp_df <-  
    data.frame(a = rnorm(100, 0, 1),
                      b = rnorm(100, 0.5, 1),
                      c = rnorm(100, -0.5, 1),
                      d = rnorm(100, 1, 1),
                      e = rnorm(100, -1, 1)) %>%
    tidyr::gather()

并生成堆积直方图:

tmp_df %>%
    ggplot(aes(x = value, fill = key)) +
    geom_histogram(binwidth = 0.1, position = 'stack')

enter image description here

一切都很好,在每个垃圾箱中,我们有5个不同颜色的条形图,显示每组垃圾箱的数量。

如果我只想显示每个垃圾箱的前N个(比如说N = 2个)组的计数,并将其他计数分类并汇总到“其他”组中,我该怎么办?

例如,对于N = 2且bin以零为中心,我想将ac的数量显示为单独的条落入此区间,但是将条形长度组合在一起bde合而为一。对于以约-1.4为中心的bin,我想显示组ec的计数,但要汇总其他两个。

2 个答案:

答案 0 :(得分:3)

您可以通过创建一个新的分组变量(我们将调用group)来执行此操作,对于每个分箱,key的值为key的前两个等级{{ 1}}或other用于key的其他三个级别。要使其工作,请在绘制数据之前对数据进行bin和tally,然后创建新的group列并将其用作fill中的ggplot美学。

library(dplyr)
library(ggplot2)

# Set a seed for reproducibility
set.seed(59)
tmp_df <-  
  data.frame(a = rnorm(100, 0, 1),
             b = rnorm(100, 0.5, 1),
             c = rnorm(100, -0.5, 1),
             d = rnorm(100, 1, 1),
             e = rnorm(100, -1, 1)) %>%
  tidyr::gather()

在下面的代码中,我们将数据分区并创建新的分组变量。我使用了0.2个单位宽的箱子,标签等于箱子的中点。要创建group列,我们使用rank在每个bin中查找key的两个最常见值,并将其余值设置为&#34;其他&#34;。

tmp_df = tmp_df %>% 
  group_by(key, 
           bins=cut(value, seq(-10,10,0.2), labels=seq(-9.9,9.9,0.2))) %>%
  tally %>%
  group_by(bins) %>%
  mutate(group = ifelse(key %in% key[rank(-n, ties="first") %in% 1:2], key, "other")) %>%
  arrange(bins, key)

现在,对于我们使用geom_bar的情节,我们会填充上面创建的新group列。此外,我们将bins(bin标签)从factor转换为numeric,这样x轴将是连续的,而不是离散的。

tmp_df %>%
  ungroup %>%
  mutate(bins = as.numeric(as.character(bins))) %>%
  ggplot(aes(x=bins, y=n, fill = group)) +
  geom_bar(stat='identity') +
  scale_fill_manual(values=c(hcl(seq(15,375,length.out=6)[1:5],100,65),"black"))

如果这是您的想法,请告诉我。

enter image description here

答案 1 :(得分:2)

我使用了一种后期方法。 ggplot创建自己的数据框来绘制图形。数据框包含所有细节,您可以明智地使用它们。

# Let's create a data set with set.seed().
library(dplyr)
library(tidyr)
library(ggplot2)
library(gridExtra)

set.seed(111)
tmp_df <-  data.frame(a = rnorm(100, 0, 1),
                      b = rnorm(100, 0.5, 1),
                      c = rnorm(100, -0.5, 1),
                      d = rnorm(100, 1, 1),
                      e = rnorm(100, -1, 1)) %>%
tidyr::gather()

# Save the original data
tmp_df %>%
ggplot(aes(x = value, fill = key)) +
geom_histogram(binwidth = 0.1, position = 'stack') -> g

现在使用g创建新数据框。您可以在下面看到此数据框的外观。

# Create a data frame
ggplot_build(g)$data[[1]] %>%
data.frame -> temp

#     fill y count    x  xmin  xmax density ncount ndensity PANEL group ymin ymax colour size linetype
#1 #E76BF3 1     1 -4.2 -4.25 -4.15     0.1  0.125     1.25     1     5    0    1     NA  0.5        1
#2 #00B0F6 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     4    1    1     NA  0.5        1
#3 #00BF7D 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     3    1    1     NA  0.5        1
#4 #A3A500 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     2    1    1     NA  0.5        1
#5 #F8766D 1     0 -4.2 -4.25 -4.15     0.0  0.000     0.00     1     1    1    1     NA  0.5        1
#6 #E76BF3 0     0 -4.1 -4.15 -4.05     0.0  0.000     0.00     1     5    0    0     NA  0.5        1

我想检查每组的颜色分配方式。所以我拿了一部分x轴为0的数据。此信息将在稍后使用。

# Check how colors are assigned to each group

filter(temp, x == 0) %>%
select(fill) %>%
unlist %>%
rev

#     fill5     fill4     fill3     fill2     fill1 
# "#F8766D" "#A3A500" "#00BF7D" "#00B0F6" "#E76BF3"

然后,我想稍微操纵一下数据框。为了找到每个组的前2个组(对于每个bin),我从ymin中减去ymax并创建了一个名为y2的新列。此列中的值说明哪些组保持在前两个位置。因此,对于每个组(每个x值),我使用y2按降序排列数据。然后,我将y2中的值替换为第3至第5位的组。如果有关系,则在每个组中选择第一个。

temp %>%
mutate(y2 = ymax - ymin) %>%
arrange(x, desc(y2)) %>%
group_by(x) %>%
mutate(group = as.character(c(group[1:2], rep(6, times = 3)))) %>%
ungroup -> temp2

最后一步是再次绘制一个数字。由于eipi10使用了geom_bar,我使用了相同的功能。

ggplot(data = temp2, aes(x = x, y = y2, fill = group)) +
geom_bar(width = 0.1, stat = "identity") +
scale_fill_manual(name = "key", labels = c("a", "b", "c", "d", "e", "others"),
           values = c("#F8766D", "#A3A500", "#00BF7D", "#00B0F6", "#E76BF3", "#000000")) +
labs(x = "value", y = "count") -> g2

enter image description here

对于下面的比较图

arrangeGrobe(g, g2, ncol = 2) -> g3
ggsave(g3, file = "whatever.png", width = 12, height = 9)

与原图(左)比较

enter image description here