File: showLabels.R

package info (click to toggle)
car 3.1-3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,520 kB
  • sloc: makefile: 2
file content (150 lines) | stat: -rw-r--r-- 5,508 bytes parent folder | download | duplicates (3)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
# last modified 25 Februrary 2010 by J. Fox
# rewritten 15 April 2010 S Weisberg
# 2013-02-07 S. Weisberg bug fix for use with 'scatterplot' with groups.
#   Added an argument to showLabels1 'all' that gives a list of two
#   elements for the original labels and subset indicator.  See
#   scatterplot.R for an example of its use.
#   If a list of cases to be labelled is supplied, id.n is needed only
#   if all n labels are to be printed.
# 2014-03-12 added new id.method "r" that labels using order(abs(y), decreasing=TRUE)
# 2016-05-16 added argument id.location = c("lr", "ab") for location of point labels
# 2017-01-08 added "avoid" to id.location arg. J. Fox
# 2017-01-08 removed ".id" from arg names for showLabels()
# 2017-01-10 special handling for method="none".
# 2017-02-13 fixed showLabels1() when location="avoid"
# 2017-03-25: don't supply names if indexes are the same as labels. J. Fox
# 2022-10-04: pointLabel() is now in the car package.

showLabels <- function(x, y, labels=NULL, method="identify",
     n = length(x), cex=1, col=carPalette()[1], 
     location=c("lr", "ab", "avoid"), ...) {
  location <- match.arg(location)
  res <- NULL
  method <- if(is.list(method)) method else list(method)
  for (meth in method){
     if (length(meth) == 1 && is.character(meth) && meth == "none") next
     res <- c(res, showLabels1(x, y, labels, meth, n, cex,
              col, location, ...))
  }
  return(if(is.null(res)) invisible(res) else res)
  }

showLabels1 <- function(x, y, labels=NULL, id.method="identify",
	   id.n = length(x), id.cex=1, id.col=carPalette()[1], 
	   id.location="lr", all=NULL, ...) { 
# If labels are NULL, try to get the labels from x:
  if (is.null(labels)) labels <- names(x)
  if (is.null(labels)) labels <- paste(seq_along(x))
  if (is.null(id.col)) id.col <- carPalette()[1]
  if (is.null(id.location)) id.location <- "lr"
# logged-axes?
  log.x <- par("xlog")
  log.y <- par("ylog")
# id.method can be any of the following:
#    --- a list of row numbers
#    --- a list of labels
#    --- a vector of n numbers
#    --- a text string:  'identify', 'x', 'y', 'mahal', 'r'
  idmeth <- pmatch(id.method[1], c("x", "y", "mahal", "identify", "r"))
  if(!is.na(idmeth)) 
    idmeth <- c("x", "y", "mahal", "identify", "r")[idmeth]
# if idmeth is NA, then id.method must be <= n numbers or labels
  id.var <- NULL
  if(is.na(idmeth)){
    if(is.null(all)) 
      all <- list(labels=labels, subs=rep(TRUE, length(labels)))
    names(all$labels) <- all$labels
    if(length(id.method) >= length(x)){
      id.var <- id.method[which(all$subs)]
      id.n <- min(id.n, length(id.var))
      }
    else {
      id.var <- rep(0, length(x))
      names(id.var) <- labels
      inSubset <- all$labels[all$subs] %in% all$labels[id.method]
      id.var[inSubset] <- 1
      id.n <- sum(inSubset)
      }
  }
  else {
# use identify?
  if(idmeth == "identify"){
    	  result <- labels[identify(x, y, labels, n=length(x), 
    	                            cex=id.cex, col=id.col)]
    	  if(length(result) > 0) return(unique(result)) else return(NULL)
  }
# missing values need to be removed
	ismissing <- is.na(x) | is.na(y) | is.na(labels)
	if( any(ismissing) ) {
		x <- x[!ismissing]
		y <- y[!ismissing]
		labels <- labels[!ismissing]
	}
# other methods:
  id.var <- switch(id.method,
		x = if(log.x==TRUE)
          suppressWarnings(if(all(x) > 0)
				   abs(log(x) - mean(log(x))) else
           return(invisible(NULL)))  else
           abs(x - mean(x)),
		y = if(log.y==TRUE)
          suppressWarnings(if(all(y) > 0)
					 abs(log(y) - mean(log(y))) else
           return(invisible(NULL)))  else
           abs(y - mean(y)),
		r = if(log.y==TRUE)
					suppressWarnings(if(all(y) > 0)
					 abs(log(y)) else
					 return(invisible(NULL)))  else
					 abs(y),
    mahal = if(log.x == TRUE & log.y == TRUE) {
          suppressWarnings(if(all(x) > 0 & all(y) > 0)
					 rowSums( qr.Q(qr(cbind(1, log(x), log(y))))^2 ) else
           return(invisible(NULL))) } else {
            if(log.x == TRUE) {
             suppressWarnings(if(all(x) > 0 )
						 rowSums( qr.Q(qr(cbind(1, log(x), y)))^2 ) else
             return(invisible(NULL))) } else {
            if(log.y == TRUE) {
             suppressWarnings(if(all(y) > 0 )
							rowSums( qr.Q(qr(cbind(1, x, log(y))))^2 ) else
              return(invisible(NULL)))  } else {
              rowSums( qr.Q(qr(cbind(1, x, y)))^2 ) }}})
     }
# require id.n positive
  if(id.n <= 0L) return(invisible(NULL))
# criterion
  ind <-  order(id.var, decreasing=TRUE)[1L:min(length(id.var), id.n)]
# position, now depends on id.location (as of 5/16/2016)
  if (id.location != "avoid"){
      if(id.location == "lr"){
      mid <- mean(if(par("xlog")==TRUE) 10^(par("usr")[1:2]) else
                  par("usr")[1:2])
    	labpos <- c(4,2)[1+as.numeric(x > mid)]
      } else {
        mid <- mean(if(par("ylog")==TRUE) 10^(par("usr")[3:4]) else
          par("usr")[3:4])
        labpos <- c(3,1)[1+as.numeric(y > mid)]
      }
    # print
    	for (i in ind) {
    		text(x[i], y[i], labels[i], cex = id.cex, xpd = TRUE,
    			col = id.col, pos = labpos[i], offset = 0.25)}
  }
  else pointLabel(c(x[ind], x[ind]), c(y[ind], y[ind]),
                c(paste0(" ", labels[ind], " "), rep(" ", length(ind))),
                cex=id.cex, xpd=TRUE, col=id.col)
  if (any(as.character(ind) != labels[ind])) names(ind) <- labels[ind]
  result <- ind
  if (length(result) == 0) return(NULL) else return(result)
}