# File src/library/stats/R/symnum.R # Part of the R package, https://www.R-project.org # # Copyright (C) 1995-2012 The R Core Team # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # A copy of the GNU General Public License is available at # https://www.R-project.org/Licenses/ symnum <- function(x, cutpoints = c( .3, .6, .8, .9, .95), symbols = if(numeric.x) c(" ", ".", ",", "+", "*", "B") else c(".", "|"), legend = length(symbols) >= 3, na = "?", eps = 1e-5, numeric.x = is.numeric(x), corr = missing(cutpoints) && numeric.x, show.max = if(corr) "1", show.min = NULL, abbr.colnames = has.colnames, lower.triangular = corr && is.numeric(x) && is.matrix(x), diag.lower.tri = corr && !is.null(show.max)) { ## Martin Maechler, 21 Jan 1994; Dedicated to Benjamin Schaad, born that day ##--------------- Argument checking ----------------------------- if(length(x) == 0L) return(noquote(if(is.null(d <- dim(x)))character() else array("", dim=d))) has.na <- any(nax <- is.na(x)) if(numeric.x) { force(corr) # missingness.. cutpoints <- sort(cutpoints) if(corr) cutpoints <- c(0, cutpoints, 1) if(anyDuplicated(cutpoints) || (corr && (any(cutpoints > 1) || any(cutpoints < 0)) )) stop(if(corr) gettext("'cutpoints' must be unique in 0 < cuts < 1, but are = ") else gettext("'cutpoints' must be unique, but are = "), paste(format(cutpoints), collapse="|"), domain = NA) nc <- length(cutpoints) minc <- cutpoints[1L] maxc <- cutpoints[nc] range.msg <- if(corr) gettext("'x' must be between -1 and 1") else gettextf("'x' must be between %s and %s", format(minc), format(maxc)) if(corr) x <- abs(x) else if(any(x < minc - eps, na.rm=TRUE)) stop(range.msg, domain = NA) if ( any(x > maxc + eps, na.rm=TRUE)) stop(range.msg, domain = NA) ns <- length(symbols) symbols <- as.character(symbols) if(anyDuplicated(symbols)) stop("'symbols' must be unique, but are = ", paste(symbols, collapse="|"), domain = NA) if(nc != ns+1) if(corr) stop("number of 'cutpoints' must be one less than number of symbols") else stop("number of 'cutpoints' must be one more than number of symbols") iS <- cut(x, breaks = cutpoints, include.lowest = TRUE, labels = FALSE) if(any(ii <- is.na(iS))) { ##-- can get 0, if x[i]== minc --- only case ? iS[which(ii)[!is.na(x[ii]) & (abs(x[ii] - minc) < eps)]] <- 1#-> symbol[1L] } } ## else if(!is.logical(x)) ## stop("'x' must be numeric or logical") else { ## assume logical x : no need for cut(points) if(!missing(symbols) && length(symbols) != 2L) stop("must have 2 'symbols' for logical 'x' argument") iS <- x + 1 # F = 1, T = 2 } if(has.na) { ans <- character(length(iS)) if((has.na <- is.character(na))) ans[nax] <- na ans[!nax] <- symbols[iS[!nax]] } else ans <- symbols[iS] if(numeric.x) { if(!is.null(show.max)) ans[x >= maxc - eps] <- if(is.character(show.max)) show.max else format(maxc, digits=1) if(!is.null(show.min)) ans[x <= minc + eps] <- if(is.character(show.min)) show.min else format(minc, digits=1) } if(lower.triangular && is.matrix(x)) ans[!lower.tri(x, diag = diag.lower.tri)] <- "" attributes(ans) <- attributes(x) if(is.array(ans)&& (rank <- length(dim(x))) >= 2L) { # `fix' column names has.colnames <- !is.null(dimnames(ans)) if(!has.colnames) { dimnames(ans) <- vector("list",rank) } else { has.colnames <- length(dimnames(ans)[[2L]]) > 0L } if((is.logical(abbr.colnames) || is.numeric(abbr.colnames)) && abbr.colnames) { dimnames(ans)[[2L]] <- abbreviate(dimnames(ans)[[2L]], minlength = abbr.colnames) ## dropped further abbrev. depending on getOption("width") } else if(is.null(abbr.colnames) || is.null(dimnames(ans)[[2L]])) dimnames(ans)[[2L]] <- rep("", dim(ans)[2L]) else if(!is.logical(abbr.colnames)) stop("invalid 'abbr.colnames'") } if(legend) { legend <- c(rbind(sapply(cutpoints,format), c(sQuote(symbols),"")), if(has.na) paste(" ## NA:", sQuote(na))) attr(ans,"legend") <- paste(legend[-2*(ns+1)], collapse=" ") } noquote(ans) }