Rev 40906 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
hist <- function(x, ...) UseMethod("hist")hist.default <-function (x, breaks = "Sturges", freq = NULL,probability = !freq, include.lowest= TRUE,right= TRUE, density = NULL, angle = 45,col = NULL, border = NULL,main = paste("Histogram of" , xname),xlim = range(breaks), ylim = NULL,xlab = xname, ylab,axes = TRUE, plot = TRUE, labels = FALSE, nclass = NULL, ...){if (!is.numeric(x))stop("'x' must be numeric")xname <- paste(deparse(substitute(x), 500), collapse="\n")n <- length(x <- x[is.finite(x)])use.br <- !missing(breaks)if(use.br) {if(!missing(nclass))warning("'nclass' not used when 'breaks' is specified")}else if(!is.null(nclass) && length(nclass) == 1)breaks <- nclassuse.br <- use.br && (nB <- length(breaks)) > 1if(use.br)breaks <- sort(breaks)else { # construct vector of breaksif(!include.lowest) {include.lowest <- TRUEwarning("'include.lowest' ignored as 'breaks' is not a vector")}if(is.character(breaks)) {breaks <- match.arg(tolower(breaks),c("sturges", "fd","freedman-diaconis", "scott"))breaks <- switch(breaks,sturges = nclass.Sturges(x),"freedman-diaconis" =,fd = nclass.FD(x),scott = nclass.scott(x),stop("unknown 'breaks' algorithm"))} else if(is.function(breaks)) {breaks <- breaks(x)}if(!is.numeric(breaks) || !is.finite(breaks) || breaks < 1)stop("invalid number of 'breaks'")breaks <- pretty (range(x), n = breaks, min.n = 1)nB <- length(breaks)if(nB <= 1) ##-- Impossible !stop("hist.default: pretty() error, breaks=", format(breaks))}## Do this *before* adding fuzz or logic breaks down...h <- diff(breaks)equidist <- !use.br || diff(range(h)) < 1e-7 * mean(h)if (!use.br && any(h <= 0))stop("'breaks' are not strictly increasing")freq1 <- freq # we want to do missing(freq) laterif (is.null(freq)) {freq1 <- if(!missing(probability)) !as.logical(probability) else equidist} else if(!missing(probability) && any(probability == freq))stop("'probability' is an alias for '!freq', however they differ.")## Fuzz to handle cases where points are "effectively on"## the boundaries## As one break point could be very much larger than the others,## as from 1.9.1 we no longer use the range. (PR#6931)## diddle <- 1e-7 * max(abs(range(breaks)))diddle <- 1e-7 * stats::median(diff(breaks))fuzz <- if(right)c(if(include.lowest) - diddle else diddle,rep.int(diddle, length(breaks) - 1))elsec(rep.int(-diddle, length(breaks) - 1),if(include.lowest) diddle else -diddle)fuzzybreaks <- breaks + fuzzh <- diff(fuzzybreaks)storage.mode(x) <- "double"storage.mode(fuzzybreaks) <- "double"## With the fuzz adjustment above, the "right" and "include"## arguments are often irrelevant (not with integer data!)counts <- .C("bincount",x,as.integer(n),fuzzybreaks,as.integer(nB),counts = integer(nB - 1),right = as.logical(right),include= as.logical(include.lowest), naok = FALSE,NAOK = FALSE, DUP = FALSE, PACKAGE = "base") $countsif (any(counts < 0))stop("negative 'counts'. Internal Error in C-code for \"bincount\"")if (sum(counts) < n)stop("some 'x' not counted; maybe 'breaks' do not span range of 'x'")dens <- counts/(n*h)mids <- 0.5 * (breaks[-1] + breaks[-nB])r <- structure(list(breaks = breaks, counts = counts,intensities = dens,density = dens, mids = mids,xname = xname, equidist = equidist),class="histogram")if (plot) {plot(r, freq = freq1, col = col, border = border,angle = angle, density = density,main = main, xlim = xlim, ylim = ylim, xlab = xlab, ylab = ylab,axes = axes, labels = labels, ...)invisible(r)}else { ## plot is FALSE## make an effort to warn about "non sensical" arguments:nf <- names(formals()) ## all formals but those:nf <- nf[is.na(match(nf, c("x", "breaks", "nclass", "plot","include.lowest", "right")))]missE <- lapply(nf, function(n)substitute(missing(.), list(. = as.name(n))))not.miss <- ! sapply(missE, eval, envir = environment())if(any(not.miss))warning(sprintf(ngettext(sum(not.miss),"argument %s is not made use of","arguments %s are not made use of"),paste(sQuote(nf[not.miss]), collapse=", ")),domain = NA)r}}plot.histogram <-function (x, freq = equidist, density = NULL, angle = 45,col = NULL, border = par("fg"), lty = NULL,main = paste("Histogram of", paste(x$xname, collapse="\n")),sub = NULL,xlab = x$xname, ylab,xlim = range(x$breaks), ylim = NULL,axes = TRUE, labels = FALSE, add = FALSE, ...){equidist <-if(is.logical(x$equidist)) x$equidistelse { h <- diff(x$breaks) ; diff(range(h)) < 1e-7 * mean(h) }if(freq && !equidist)warning("the AREAS in the plot are wrong -- rather use freq=FALSE")y <- if (freq) x$counts else { ## x$density -- would be enough, but## for back compatibilityy <- x$density; if(is.null(y)) x$intensities else y}nB <- length(x$breaks)if(is.null(y) || 0 == nB) stop("'x' is wrongly structured")if(!add) {if(is.null(ylim))ylim <- range(y, 0)if (missing(ylab))ylab <- if (!freq) "Density" else "Frequency"plot.new()plot.window(xlim, ylim, "") #-> ylim's default from 'y'title(main = main, sub = sub, xlab = xlab, ylab = ylab, ...)if(axes) {axis(1, ...)axis(2, ...)}}rect(x$breaks[-nB], 0, x$breaks[-1], y,col = col, border = border,angle = angle, density = density, lty = lty)if((logl <- is.logical(labels) && labels) || is.character(labels))text(x$mids, y,labels = if(logl) {if(freq) x$counts else round(x$density,3)} else labels,adj = c(0.5, -0.5))invisible()}lines.histogram <- function(x, ...) plot.histogram(x, ..., add = TRUE)