Rev 5261 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
### Copyright (C) 2001-2006 Deepayan Sarkar <Deepayan.Sarkar@R-project.org>###### This file is part of the lattice package for R.### It is made available under the terms of the GNU General Public### License, version 2, or at your option, any later version,### incorporated herein by reference.###### 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.###### You should have received a copy of the GNU General Public### License along with this program; if not, write to the Free### Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,### MA 02110-1301, USA## from R 2.4.0 onwards, hist.default produces a warning when any## 'unused' arguments are supplied. Before then, all ... arguments## used to be supplied to hist(), so arguments to hist() could be## supplied that way. This is no longer possible, so the following## wrapper is being added to capture undesirable arguments.hist.constructor <-function(x, breaks,include.lowest = TRUE,right = TRUE, ...){if (is.numeric(breaks) && length(breaks) > 1)hist(as.numeric(x), breaks = breaks, plot = FALSE,include.lowest = include.lowest,right = right)elsehist(as.numeric(x), breaks = breaks, right = right, plot = FALSE)}prepanel.default.histogram <-function(x,breaks,equal.widths = TRUE,type = "density",nint = round(log2(length(x)) + 1),...){if (length(x) < 1) prepanel.null()else{if (is.null(breaks)){breaks <-if (is.factor(x)) seq_len(1 + nlevels(x)) - 0.5else if (equal.widths) do.breaks(range(x, finite = TRUE), nint)else quantile(x, 0:nint/nint, na.rm = TRUE)}h <-hist.constructor(x, breaks = breaks, ...)y <-if (type == "count") h$countselse if (type == "percent") 100 * h$counts / length(x)else h$intensitieslist(xlim =if (is.factor(x)) levels(x)else scale.limits(c(x, h$breaks)),## if (is.factor(x)) levels(x)## else range(x, h$breaks, finite = TRUE),ylim = range(0, y, finite = TRUE),dx = 1,dy = 1)}}panel.histogram <-function(x,breaks,equal.widths = TRUE,type = "density",nint = round(log2(length(x)) + 1),alpha = plot.polygon$alpha,col = plot.polygon$col,border = plot.polygon$border,lty = plot.polygon$lty,lwd = plot.polygon$lwd,...){plot.polygon <- trellis.par.get("plot.polygon")xscale <- current.panel.limits()$xlimpanel.lines(x = xscale[1] + diff(xscale) * c(0.05, 0.95),y = c(0,0),col = border, lty = lty, lwd = lwd, alpha = alpha)## grid.lines(x = c(0.05, 0.95),## y = unit(c(0,0), "native"),## gp = gpar(col = border, lty = lty, lwd = lwd, alpha = alpha),## default.units = "npc")if (length(x) > 0){if (is.null(breaks)){breaks <-if (is.factor(x)) seq_len(1 + nlevels(x)) - 0.5else if (equal.widths) do.breaks(range(x, finite = TRUE), nint)else quantile(x, 0:nint/nint, na.rm = TRUE)}h <- hist.constructor(x, breaks = breaks, ...)## FIXME: change to this after 2.5.0:## y <-## switch(type,## count = h$counts,## percent = 100 * h$counts/length(x),## density = h$intensities)y <-if (type == "count") h$countselse if (type == "percent") 100 * h$counts/length(x)else h$intensitiesbreaks <- h$breaksnb <- length(breaks)if (length(y) != nb-1) warning("problem with 'hist' computations")if (nb > 1){panel.rect(x = breaks[-nb],y = 0,height = y,width = diff(breaks),col = col, alpha = alpha,border = border, lty = lty,lwd = lwd,just = c("left", "bottom"))}}}histogram <- function(x, data, ...) UseMethod("histogram")histogram.factor <- histogram.numeric <-function(x, data = NULL, xlab = deparse(substitute(x)), ...){ocall <- sys.call(sys.parent()); ocall[[1]] <- quote(histogram)ccall <- match.call()if (!is.null(ccall$data))warning("explicit 'data' specification ignored")ccall$data <- environment() # list(x = x)ccall$xlab <- xlabccall$x <- ~xccall[[1]] <- quote(lattice::histogram)ans <- eval.parent(ccall)ans$call <- ocallans}histogram.formula <-function(x,data = NULL,allow.multiple = is.null(groups) || outer,outer = TRUE,auto.key = FALSE,aspect = "fill",panel = lattice.getOption("panel.histogram"),prepanel = NULL,scales = list(),strip = TRUE,groups = NULL,xlab,xlim,ylab,ylim,type = c("percent", "count", "density"),nint = if (is.factor(x)) nlevels(x)else round(log2(length(x)) + 1),endpoints = extend.limits(range(as.numeric(x), finite = TRUE), prop = 0.04),breaks,equal.widths = TRUE,drop.unused.levels = lattice.getOption("drop.unused.levels"),...,lattice.options = NULL,default.scales = list(),subscripts = !is.null(groups),subset = TRUE){formula <- xdots <- list(...)groups <- eval(substitute(groups), data, environment(formula))subset <- eval(substitute(subset), data, environment(formula))if (!is.null(lattice.options)){oopt <- lattice.options(lattice.options)on.exit(lattice.options(oopt), add = TRUE)}## Step 1: Evaluate x, y, etc. and do some preprocessingform <-latticeParseFormula(formula, data, subset = subset,groups = groups, multiple = allow.multiple,outer = outer, subscripts = TRUE,drop = drop.unused.levels)groups <- form$groupsif (!is.function(panel)) panel <- eval(panel)if (!is.function(strip)) strip <- eval(strip)if ("subscripts" %in% names(formals(panel))) subscripts <- TRUEif (subscripts) subscr <- form$subscrprepanel <-if (is.function(prepanel)) prepanelelse if (is.character(prepanel)) get(prepanel)else eval(prepanel)cond <- form$conditionx <- form$rightif (length(cond) == 0){strip <- FALSEcond <- list(gl(1, length(x)))}if (missing(xlab)) xlab <- form$right.nameif (missing(ylab)) ylab <- TRUE##if(!(is.numeric(x) || is.factor(x)))## warning("x should be numeric")##x <- as.numeric(x)## create a skeleton trellis object with the## less complicated components:foo <-do.call("trellis.skeleton",c(list(formula = formula,cond = cond,aspect = aspect,strip = strip,panel = panel,xlab = xlab,ylab = ylab,xlab.default = form$right.name,ylab.default = "dummy",lattice.options = lattice.options), dots))dots <- foo$dots # arguments not processed by trellis.skeletonfoo <- foo$foofoo$call <- sys.call(sys.parent()); foo$call[[1]] <- quote(histogram)## Step 2: Compute scales.common (leaving out limits for now)if (is.character(scales)) scales <- list(relation = scales)scales <- updateList(default.scales, scales)foo <- c(foo, do.call("construct.scales", scales))## Step 3: Decide if limits were specified in call:have.xlim <- !missing(xlim)if (!is.null(foo$x.scales$limit)){have.xlim <- TRUExlim <- foo$x.scales$limit}have.ylim <- !missing(ylim)if (!is.null(foo$y.scales$limit)){have.ylim <- TRUEylim <- foo$y.scales$limit}## Step 4: Decide if log scales are being used:have.xlog <- !is.logical(foo$x.scales$log) || foo$x.scales$loghave.ylog <- !is.logical(foo$y.scales$log) || foo$y.scales$logif (have.xlog){xlog <- foo$x.scales$logxbase <-if (is.logical(xlog)) 10else if (is.numeric(xlog)) xlogelse if (xlog == "e") exp(1)x <- log(x, xbase)if (have.xlim) xlim <- logLimits(xlim, xbase)}if (have.ylog){warning("Can't have log Y-scale")have.ylog <- FALSEfoo$y.scales$log <- FALSE}## should type default to density? "Yes" when a relative## frequency histogram is going to be misleading.if (missing(breaks)) # explicit NULL, or function, or character is finebreaks <- # use nint and endpointsif (is.factor(x)) seq_len(1 + nlevels(x)) - 0.5else do.breaks(as.numeric(endpoints), nint)prefer.density <-(is.function(breaks) ||(is.null(breaks) && !equal.widths) ||(is.numeric(breaks) && {ddb <- diff(diff(breaks))identical(FALSE, all.equal(ddb, numeric(length(ddb))))}))if (missing(type) && prefer.density)type <- "density"type <- match.arg(type)if (prefer.density && type != "density")warning(gettextf("type='%s' can be misleading in this context", type))## this is normally done earlier (in trellis.skeleton), but in## this case we needed to wait till type is determinedfoo$ylab.default <-switch(type,count = gettext("Count"),percent = gettext("Percent of Total"),density = gettext("Density"))## Step 5: Process condcond.max.level <- unlist(lapply(cond, nlevels))## Step 6: Determine packetsfoo$panel.args.common <-c(list(breaks = breaks,type = type,equal.widths = equal.widths,nint = nint),dots)if (subscripts) foo$panel.args.common$groups <- groupsnpackets <- prod(cond.max.level)if (npackets != prod(sapply(foo$condlevels, length)))stop("mismatch in number of packets")foo$panel.args <- vector(mode = "list", length = npackets)foo$packet.sizes <- numeric(npackets)if (npackets > 1){dim(foo$packet.sizes) <- sapply(foo$condlevels, length)dimnames(foo$packet.sizes) <- lapply(foo$condlevels, as.character)}cond.current.level <- rep(1, length(cond))for (packet.number in seq_len(npackets)){id <- compute.packet(cond, cond.current.level)foo$packet.sizes[packet.number] <- sum(id)foo$panel.args[[packet.number]] <- list(x = x[id])if (subscripts)foo$panel.args[[packet.number]]$subscripts <-subscr[id]cond.current.level <-cupdate(cond.current.level,cond.max.level)}more.comp <- c(limits.and.aspect(prepanel.default.histogram,prepanel = prepanel,have.xlim = have.xlim, xlim = xlim,have.ylim = have.ylim, ylim = ylim,x.relation = foo$x.scales$relation,y.relation = foo$y.scales$relation,panel.args.common = foo$panel.args.common,panel.args = foo$panel.args,aspect = aspect,npackets = npackets,x.axs = foo$x.scales$axs,y.axs = foo$y.scales$axs),cond.orders(foo))foo[names(more.comp)] <- more.compif (is.null(foo$legend) && !is.null(groups) &&(is.list(auto.key) || (is.logical(auto.key) && auto.key))){foo$legend <-list(list(fun = "drawSimpleKey",args =updateList(list(text = levels(as.factor(groups)),points = FALSE,rectangles = TRUE,lines = FALSE),if (is.list(auto.key)) auto.key else list())))foo$legend[[1]]$x <- foo$legend[[1]]$args$xfoo$legend[[1]]$y <- foo$legend[[1]]$args$yfoo$legend[[1]]$corner <- foo$legend[[1]]$args$cornernames(foo$legend) <-if (any(c("x", "y", "corner") %in% names(foo$legend[[1]]$args)))"inside"else"top"if (!is.null(foo$legend[[1]]$args$space))names(foo$legend) <- foo$legend[[1]]$args$space}class(foo) <- "trellis"foo}