R - tidyverse / ggplot条形图,带有自定义离散数据标签并按一个变量排序?

时间:2018-06-16 14:22:58

标签: r ggplot2 geom-bar

我有一个数据框,我在R中学习tidyverse方法,如下所示:

> glimpse(data)
Observations: 16
Variables: 6
$ True.species  <fct> Badger, Blackbird, Brown hare, Domestic cat, Domestic d...
$ misidentified <dbl> 17, 16, 59, 20, 12, 24, 28, 6, 3, 7, 191, 19, 110, 21, ...
$ missed        <dbl> 61, 106, 7, 24, 16, 160, 110, 12, 15, 37, 200, 58, 259,...
$ Total         <dbl> 78, 122, 66, 44, 28, 184, 138, 18, 18, 44, 391, 77, 369...
$ PrMissed      <dbl> 0.7820513, 0.8688525, 0.1060606, 0.5454545, 0.5714286, ...
$ PrMisID       <dbl> 0.21794872, 0.13114754, 0.89393939, 0.45454545, 0.42857...

以下是dput()

data <- structure(list(True.species = structure(c(1L, 2L, 3L, 5L, 6L, 
7L, 8L, 9L, 13L, 16L, 17L, 18L, 20L, 21L, 22L, 23L), .Label = c("Badger", 
"Blackbird", "Brown hare", "Crow", "Domestic cat", "Domestic dog", 
"Grey squirrel", "Hedgehog", "Horse", "Human", "Jackdaw", "Livestock", 
"Magpie", "Muntjac", "Nothing", "Pheasant", "Rabbit", "Red fox", 
"Red squirrel", "Roe Deer", "Small rodent", "Stoat or Weasel", 
"Woodpigeon"), class = "factor"), misidentified = c(17, 16, 59, 
20, 12, 24, 28, 6, 3, 7, 191, 19, 110, 21, 5, 13), missed = c(61, 
106, 7, 24, 16, 160, 110, 12, 15, 37, 200, 58, 259, 473, 9, 17
), Total = c(78, 122, 66, 44, 28, 184, 138, 18, 18, 44, 391, 
77, 369, 494, 14, 30), PrMissed = c(0.782051282051282, 0.868852459016393, 
0.106060606060606, 0.545454545454545, 0.571428571428571, 0.869565217391304, 
0.797101449275362, 0.666666666666667, 0.833333333333333, 0.840909090909091, 
0.51150895140665, 0.753246753246753, 0.70189701897019, 0.95748987854251, 
0.642857142857143, 0.566666666666667), PrMisID = c(0.217948717948718, 
0.131147540983607, 0.893939393939394, 0.454545454545455, 0.428571428571429, 
0.130434782608696, 0.202898550724638, 0.333333333333333, 0.166666666666667, 
0.159090909090909, 0.48849104859335, 0.246753246753247, 0.29810298102981, 
0.0425101214574899, 0.357142857142857, 0.433333333333333)), row.names = c(NA, 
-16L), class = "data.frame")

我设法用ggplot()制作了我想要的基本情节如下:

ggplot(data = data, aes(x = True.species, y = PrMissed)) + geom_bar(stat = "identity")

enter image description here

但有三件事我无法弄明白该怎么做:

  1. 我想要一个堆积条形图,其中变量PrMissedPrMisID在彼此之上。请注意,PrMissed + PrMisID == 1表示数据框中的每一行,因此最终的绘图将具有相同的高堆栈,但每个包含两种颜色(如何指定它们?),一个用于PrMissed,另一个用于{{ 1}}。
  2. 我希望条形图的顺序按PrMisID变量的升序排列,以便PrMissed位于一端,Brown hare位于另一端。
  3. 我更喜欢这个情节在其侧面“翻转”,以便标签(动物名称如“Brown hare”)位于左侧并且更易于阅读。更复杂的是,不是标签只是简单地说动物名称,我希望它们说出相应的Small rodent值,所以例如Total会得到一个相应的轴标签,如“棕色野兔(总计= 66)”。
  4. 我一直在努力,因为我的生活无法用Brown hare找出一种公理化的方法。我知道答案可能很简单,请原谅我的无知。有人可以帮忙吗?提前谢谢。

2 个答案:

答案 0 :(得分:1)

我可以使用data.tableggplot2解决方案:

首先,您需要使用melt使您的宽表变长。然后,您正在寻找position = "stack"的{​​{1}}参数:

另外,请注意,为表格命名geom_bar是个坏主意,因为有一个名为data的函数。

data()

我忘记了排序......(和文本的轮换,所以它们是可读的):

require(data.table)
ggplot(melt(df[, .(True.species, PrMissed, PrMisID)], 
            id.vars="True.species"), 
       aes(x = True.species, y = value, fill = variable))+
   geom_bar(position = "stack", stat = "identity")

答案 1 :(得分:1)

以下是我的答案,不需要使用data.tables,而且完全基于tidyverse个套餐:

library(ggplot2)
library(reshape2)
library(magrittr)
library(dplyr)
# order Species by PrMissed value 
data$True.species <- factor(data$True.species,
                        levels = data[order(data$PrMissed, decreasing = F),"True.species"])

# reshape to have the stackable values and plot
melt(data,
 id.vars = c("True.species", "misidentified", "missed", "Total"),
 measure.vars = c("PrMissed", "PrMisID")) %>%
 mutate(x_axis_text = paste(.$True.species, "(Total = ",  .$Total, ")") ) %>%  
   ggplot(aes(x = x_axis_text, y = value, fill = variable) ) +
   geom_bar(stat = "identity") +
   coord_flip() 

这会导致像这样的情节

enter image description here

细分代码: 你的个人观点是这样完成的。

1)要具有可堆叠值,它们必须全部在一列中,因此使用melt包中的reshape2我们整理数据并在data中创建2个新列。一个是value,其中包含0到1之间的值,另一个是variable,表示该数字是否与PrMissedPrMisID

相关联

2)在melt数据之前,我们会根据True.species值将PrMissed值转换为因子。如果您愿意,可以使用decreasing = T来反转订单。

3)coord_flip()翻转x和y轴,使物种在y轴而不是y轴上,你可以在左侧轻松读取它们。