厚缊

诹图——ggcor简介(四)

厚缊 / 2020-02-04


上一期讲了quickcor()函数,说是可以解决90%的问题,今天本来是要介绍ggcor()函数,补充剩余的10%,但是想想ggcor()函数没啥可讲的,不如补充一部分cor_tbl的设计理念,以及ggcor()quickcor()的运行机制。

ggcor()函数适用场景

quickcor()几乎把需要设置的细节都自动设置好了,出图十分简单,但灵活性稍差,ggcor()则是只处理了最基本的坐标轴,其它的都由用户自己控制,更灵活。同时,由于ggcor()使用的频率并不高,所以ggcor()函数要求数据为cor_tbl对象。

library(ggcor)
args(ggcor)
## function (data, mapping = NULL, axis.x.position = "auto", axis.y.position = "auto", 
##     axis.label.drop = TRUE) 
## NULL

几个例子

在默认情况下,出图效果感觉啥都没有,十分简陋,基本看不出有啥用。

cor(mtcars) %>% 
  as_cor_tbl() %>% 
  ggcor() + geom_square()

这个例子几乎还原了quickcor()内部做的工作。

library(ggplot2)
cor(mtcars) %>% 
  as_cor_tbl() %>% 
  ggcor() + geom_point(aes(size = r, fill = r), shape = 21) +
  scale_size_area(max_size = 10) +
  theme(axis.title = element_blank()) +
  coord_fixed(xlim = c(0.5, 11.5), ylim = c(0.5, 11.5))

再看cor_tbl对象

最基本的cor_tbl对象包含五列,第一、二列.row.names.col.names是相关系数矩阵的行名和列名组合,.row.id.col.id是相关系数矩阵每个单元格的位置,需要注意的是,按照惯例,矩阵热图的第一行放置在顶端,所以.row.id进行了翻转。

df <- cor(mtcars) %>% 
  cor_tbl()
head(df)
## # A tibble: 6 x 5
##   .row.names .col.names      r .row.id .col.id
##   <chr>      <chr>       <dbl>   <int>   <int>
## 1 mpg        mpg         1          11       1
## 2 cyl        mpg        -0.852      10       1
## 3 disp       mpg        -0.848       9       1
## 4 hp         mpg        -0.776       8       1
## 5 drat       mpg         0.681       7       1
## 6 wt         mpg        -0.868       6       1

cor_tbl存储了一些特征属性,包括原相关系数矩阵的行名(.row.names)、列名(.col.names)、类型(type)、是否带对角线(show.diag)以及是否是样本分组(grouped)。

attributes(df)
## $names
## [1] ".row.names" ".col.names" "r"          ".row.id"    ".col.id"   
## 
## $class
## [1] "cor_tbl"    "tbl_df"     "tbl"        "data.frame"
## 
## $row.names
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 101 102
## [103] 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
## [120] 120 121
## 
## $.row.names
##  [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
## [11] "carb"
## 
## $.col.names
##  [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
## [11] "carb"
## 
## $type
## [1] "full"
## 
## $show.diag
## [1] TRUE
## 
## $grouped
## [1] FALSE

每一列的作用

在最初的版本里面,cor_tbl没有.row.names.col.names列,只有矩阵每个单元格的位置(.row.id.col.id),现在增加进来是基于两个方面的考虑,一是保留行列名更容易查看cor_tbl每一行是哪两个变量的相关性,也更容易发现BUG,二是后来增加的相关性网络需要用到名字列,保留了一致性更好。从以上介绍也不难看出,.row.names.col.names列对于相关系数矩阵热图是可有可无的。

.row.id.col.id列是相关系数矩阵热图可视化的基础,它指明了cor_tbl的每一行应该放在哪个位置,即.row.id.col.id分别对应最终坐标轴上的Y和X轴。空讲原理有点晕乎,我们可以看个例子。

ggplot(df, aes(.col.id, .row.id, fill = r)) + 
  geom_tile()

.row.id.col.id还是cor_tbl对象取上下三角的依据。

df %>% 
  dplyr::filter(.row.id + .col.id > 11) %>% 
  ggplot(aes(.col.id, .row.id, fill = r)) + 
  geom_tile()

这里可能有个疑问,为什么不直接使用.row.names.col.names作为Y/X坐标,我可以负责任的说,同样可以实现,但是我觉得用连续变量有好处,所以最终选择了用位置ID作为坐标。

ggplot(df, aes(.col.names, .row.names, fill = r)) + 
  geom_tile() ## 此处没有翻转Y轴

额外属性的作用

最重要的两个属性是原相关系数矩阵的行名(.row.names)、列名(.col.names),这两个属性决定了可视化中如何设置坐标轴标签。

ggplot(df, aes(.col.id, .row.id, fill = r)) + 
  geom_tile() +
  scale_x_continuous(
    name = NULL,
    breaks = 1:11, labels = get_col_name(df)) +
  scale_y_continuous(
    name = NULL,
    breaks = 1:11, labels = get_col_name(df))

df$.row.names <- factor(df$.row.names, levels = rev(get_row_name(df)))
df$.col.names <- factor(df$.col.names, levels = get_col_name(df))
ggplot(df, aes(.col.names, .row.names, fill = r)) + 
  geom_tile() 

类型(type)、是否带对角线(show.diag)两个属性主要用来在quickcor()ggcor()自动控制坐标轴、图例位置,看两个图就明白了。

quickcor(mtcars, type = "upper") + geom_colour()

quickcor(mtcars, type = "lower") + geom_colour()

小结

通过四期全部过了一遍cor_tbl及其可视化的内容,看完应该对ggcor的理解更深了。

下期预告:mantel 检验。