我有这样的数据:
Name Count
Object1 110
Object2 111
Object3 95
Object4 40
...
Object2000 1
Run Code Online (Sandbox Code Playgroud)
所以只有前 3 个对象有高计数,其余 1996 个对象少于 40 个,大多数少于 10 个。我用ggplot条形图绘制这些数据,如下所示:
ggplot(data=object_count, mapping = aes(x=object, y=count)) +
geom_bar(stat="identity") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())
Run Code Online (Sandbox Code Playgroud)
我的情节如下。如您所见,由于低计数的对象太多,因此图形的宽度很长,条形的宽度很小,这对于高计数的对象几乎是不可见的。有没有更好的方法来表示这些数据?我的目标是展示一些数量最多的物体,并展示许多数量较少的物体。有没有办法将低计数的组合在一起?
我的猜测是你的数据看起来像这样:
set.seed(1)
object_count <- tibble(
obj_num = 1:2000,
object = paste0("Object", obj_num),
count = ceiling(20 * rpois(2000, 10) / obj_num)
)
head(object_count)
## A tibble: 6 x 3
# obj_num object count
# <int> <chr> <dbl>
#1 1 Object1 160
#2 2 Object2 100
#3 3 Object3 46
#4 4 Object4 55
#5 5 Object5 56
#6 6 Object6 40
Run Code Online (Sandbox Code Playgroud)
果然,当我用 绘制它时,ggplot(object_count, aes(object, count)) + geom_col() + [theme stuff]我得到了类似的数字。
这里有一些策略“显示一些最高计数的对象并显示许多低计数的对象”。
普通的直方图在这里可能无法澄清,因为重要的大值出现的频率显着降低,并且不够突出:
ggplot(object_count, aes(count)) +
geom_histogram()
Run Code Online (Sandbox Code Playgroud)
但我们可以通过改变 y 轴来改变这一点,以更加强调小值。该pseudo_log变换对此非常有用,因为它的工作原理类似于大值的对数变换,但线性接近 -1 到 1。在此视图中,我们可以清楚地看到仅出现一种的异常值在哪里,而且还可以看到还有更多的异常值小值。binwidth = 1如果大值的具体值不如它们的一般范围那么重要,则可以将此处设置为更宽的值。
ggplot(object_count, aes(count)) +
geom_histogram(binwidth = 1) +
scale_y_continuous(trans = "pseudo_log",
breaks = c(0:3, 100, 1000), minor_breaks = NULL)
Run Code Online (Sandbox Code Playgroud)
另一种选择可能是将您的视图分成两部分,一个显示大值的详细信息,另一个显示所有小值:
object_count %>%
mutate(biggies = if_else(count > 20, "Big", "Little")) %>%
ggplot(aes(obj_num, count)) +
geom_col() +
facet_grid(~biggies, scales = "free")
Run Code Online (Sandbox Code Playgroud)
另一种选择可能是将 10 以下的所有计数集中在一起。下面的版本强调对象名称和计数,并且“其他”类别已被标记以显示它包含多少个值。
object_count %>%
mutate(group = if_else(count < 10, "Others", object)) %>%
group_by(group) %>%
summarize(avg = mean(count), count = n()) %>%
ungroup() %>%
mutate(group = if_else(group == "Others",
paste0("Others (n =", count, ")"),
group)) %>%
mutate(group = forcats::fct_reorder(group, avg)) %>%
ggplot() +
geom_col(aes(group, avg)) +
geom_text(aes(group, avg, label = round(avg, 0)), hjust = -0.5) +
coord_flip()
Run Code Online (Sandbox Code Playgroud)
如果您对总计数的份额感兴趣,您还可以查看累积计数并了解大值如何构成大份额:
object_count %>%
mutate(cuml = cumsum(count)) %>%
ggplot(aes(obj_num)) +
geom_tile(aes(y = count + lag(cuml, default = 0),
height = count))
Run Code Online (Sandbox Code Playgroud)