File: corrRect.R

package info (click to toggle)
r-cran-corrplot 0.95-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,212 kB
  • sloc: sh: 13; makefile: 5
file content (137 lines) | stat: -rw-r--r-- 4,254 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#' Draw rectangle(s) on the correlation matrix graph.
#'
#' Draw rectangle(s) after the correlation matrix plotted. SUGGESTION: It's more convenient
#' to draw rectangle(s) by using pipe operator `|>` since R 4.1.0.
#'
#' \code{corrRect} needs one of \code{index}, \code{name} and \code{namesMat} inputted.
#' While \code{corrRect.hclust} can get the members in each cluster
#' based on hierarchical clustering (\code{\link{hclust}}).
#'
#' @param corrRes List of the \code{corrplot()} returns.
#' @param index Vector, variable index of diag rect \code{c(Rect1from, Rect2from,
#' Rect3from, ..., RectNto)} on the correlation matrix graph.
#' It works when the colnames are the same as rownames, or both of them is NULL.
#' It needs \code{corrRes} inputted.
#' @param name Vector, variable name of diag rect \code{c(Rect1from, Rect2from,
#' Rect3from, ..., RectNto)} on the correlation matrix graph.
#' OIt works when the colnames are the same as rownames.
#' It needs \code{corrRes} inputted.
#' @param namesMat 4-length character vector or 4-columns character matrix,
#' represents the names of xleft, ybottom, xright, ytop correspondingly.
#' It needs \code{corrRes} inputted.
#' @param col Color of rectangles.
#' @param lwd Line width of rectangles.
#' @param \dots Additional arguments passing to function \code{rect()}.
#'
#' @return (Invisibly) returns input parameter \code{corrRes},
#' usually \code{list(corr, corrTrans, arg)}.
#'
#' @example vignettes/example-corrRect.R
#' @keywords hplot
#' @author Taiyun Wei
#' @export
corrRect = function(corrRes = NULL, index = NULL, name = NULL, namesMat = NULL,
                    col = 'black', lwd = 2, ...)
{

  if((as.integer(!is.null(index)) + as.integer(!is.null(name)) +
      as.integer(!is.null(namesMat))) > 1) {
    stop('You should just input one of index, name and namesMat!')
  }

  if(is.null(corrRes)|!is.list(corrRes)) {
    stop('List \'corrRes\' must be inputted!')
  }

  corr = corrRes$corr
  corrPos = corrRes$corrPos
  type = corrRes$arg$type

  cName = colnames(corr)
  rName = rownames(corr)

  if(!is.null(name)) {

    if(any(cName != rName)) {
      stop('colnames and rownames must be same when index or name is inputted!')
    }


    if(!all(name %in% cName)) {
      stop('Non-existent name found!')
    }

    index = unlist(lapply(name, function(n) which(cName==n)))
  }



  if(!is.null(index)) {

    if(any(cName != rName)) {
      stop('colnames and rownames must be same when index or name is inputted!')
    }


    n = length(index)
    index[-n] = index[-n] - 1

    x1 = index[-n] + 0.5
    y1 = nrow(corr) - index[-n] + 0.5
    x2 = index[-1] + 0.5
    y2 = nrow(corr) - index[-1] + 0.5
    St = S = cbind(c(x1, x1, x2, x2), c(y1, y1, y2, y2),
                   c(x2, x1, x2, x1), c(y1, y2, y1, y2))
    St[, 2] = abs(St[, 2] - nrow(corr) - 1)
    St[, 4] = abs(St[, 4] - nrow(corr) - 1)

    if(type=='upper') {
      i = which((St[, 1] - St[, 2]) > -0.1 & (St[, 3] - St[, 4]) > -0.1)
      S = S[i, ]
    }

    if(type=='lower') {
      i = which((St[, 2] - St[, 1]) > -0.1 & (St[, 4] - St[, 3]) > -0.1)
      S = S[i, ]
    }

    segments(S[, 1], S[, 2], S[, 3], S[, 4], col = col, lwd = lwd, ...)
  }

  if(!is.null(namesMat)) {

    if(is.vector(namesMat)) {
      namesMat = matrix(namesMat, ncol = 4, nrow = 1)
    }

    xy1 = getCharXY(namesMat[, 1:2, drop=FALSE], corrPos)
    xy2 = getCharXY(namesMat[, 3:4, drop=FALSE], corrPos)

    xy = cbind(xy1, xy2)

    x1 = apply(xy[, c(1, 3), drop=FALSE], 1, min) - 0.5
    y1 = apply(xy[, c(2, 4), drop=FALSE], 1, min) - 0.5
    x2 = apply(xy[, c(1, 3), drop=FALSE], 1, max) + 0.5
    y2 = apply(xy[, c(2, 4), drop=FALSE], 1, max) + 0.5

    rect(x1, y1, x2, y2, border = col, lwd = lwd, ...)
  }

  invisible(corrRes)

}


#' @noRd
getCharXY = function(x, dat) {

  res = apply(x, 1, function(n, d=dat) d[d[, 1]==n[1]&d[, 2]==n[2], 3:4])

  f = which(unlist(lapply(res, nrow))==0)
  if(length(f) > 0) {
    error  = paste(toString(unique(x[f, ])), 'paired X-Y names were not found!')
    stop(error)
  }

  return(matrix(unlist(res), byrow = TRUE, ncol = 2))
}