示例数据:
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')
一切都很好,在每个垃圾箱中,我们有5个不同颜色的条形图,显示每组垃圾箱的数量。
如果我只想显示每个垃圾箱的前N个(比如说N = 2个)组的计数,并将其他计数分类并汇总到“其他”组中,我该怎么办?
例如,对于N = 2且bin以零为中心,我想将a
和c
的数量显示为单独的条落入此区间,但是将条形长度组合在一起b
,d
和e
合而为一。对于以约-1.4为中心的bin,我想显示组e
和c
的计数,但要汇总其他两个。
答案 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"))
如果这是您的想法,请告诉我。
答案 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
对于下面的比较图
arrangeGrobe(g, g2, ncol = 2) -> g3
ggsave(g3, file = "whatever.png", width = 12, height = 9)
与原图(左)比较