# # QQ plot of smoothed residual field against model # # qqplot.ppm() QQ plot (including simulation) # # $Revision: 1.5 $ $Date: 2005/05/24 21:11:26 $ # qqplot.ppm <- function(fit, nsim=100, expr=NULL, ..., type="raw", style="mean", fast=TRUE, verbose=TRUE, plot.it=TRUE, dimyx=NULL, nrep=if(fast) 5e4 else 1e5, control=list(nrep=nrep, expand=default.expand(fit), periodic=TRUE), saveall=FALSE) { verifyclass(fit, "ppm") if(fast) { oldnpixel <- spatstat.options("npixel")[[1]] if(is.null(dimyx)) dimyx <- pmin(40, oldnpixel) spatstat.options(npixel=dimyx) } ################ How to evaluate residuals ########################## # Quantiles of the residual field will be computed. residualfield <- function(fit, ...) { d <- diagnose.ppm(fit, which="smooth", plot.it=FALSE, compute.cts=FALSE, compute.sd=FALSE, ...) return(d$smooth$Z$v) } # Data values dat <- residualfield(fit, type=type, ..., dimyx=dimyx) # How to refit the model properly! refit <- function(fit, pattern) { update.ppm(fit, Q=pattern) } ################## How to perform simulations? ####################### simulate.from.fit <- is.null(expr) if(!simulate.from.fit) { # 'expr' will be evaluated 'nsim' times if(!is.expression(expr)) stop("Argument \'expr\' should be an expression") } else{ # We will simulate from the fitted model 'nsim' times # and refit the model to these simulations # prepare rmh arguments rcontrol <- rmhcontrol(control) rmodel <- rmhmodel(fit, control=rcontrol, project=TRUE, verbose=verbose) rstart <- rmhstart(n.start=data.ppm(fit)$n) # expression to be evaluated each time expr <- expression( refit(fit, rmh.default(rmodel, rstart, rcontrol, verbose=FALSE))) } ###### Perform simulations if(verbose) cat(paste("Simulating", nsim, "realisations... ")) for(i in 1:nsim) { ei <- eval(expr) fiti <- if(simulate.from.fit) ei else if(is.ppm(ei)) ei else if(is.ppp(ei)) refit(fit, ei) else stop("result of eval(expr) is not a ppm or ppp object") resi <- residualfield(fiti, type=type, ..., dimyx=dimyx) if(i == 1) sim <- array(, dim=c(dim(resi), nsim)) sim[,,i] <- resi if(verbose) cat(paste(i, ifelse(i %% 10 == 0, "\n", ", "), sep="")) } ############ Plot them switch(style, classical = { rr <- range(c(dat,sim)) result <- qqplot(sim, dat, xlim=rr, ylim=rr, asp=1.0, xlab="Quantiles of simulation", ylab="Quantiles of data",plot.it=plot.it) title(sub=paste("Residuals:", type)) abline(0,1, lty=2) result <- append(result, list(data=dat, sim=sim, xlim=rr, ylim=rr, xlab="Quantiles of simulation", ylab="Quantiles of data", rtype=type, nsim=nsim, fit=fit, expr= if(simulate.from.fit) NULL else deparse(expr), simulate.from.fit=simulate.from.fit ) ) }, mean = { # compute quantiles corresponding to probabilities p[i] # separately in each realisation. if(verbose) cat("Calculating quantiles...") if(fast) { p <- ppoints(min(100,length(dat)), 3/8) qsim <- apply(sim, 3, quantile, probs=p, na.rm=TRUE) } else { qsim <- apply(sim, 3, sort, na.last=TRUE) } if(verbose) cat("averaging...") # sample mean of each quantile meanq <- apply(qsim, 1, mean, na.rm=TRUE) # et cetera varq <- apply(qsim, 1, var, na.rm=TRUE) sdq <- sqrt(varq) q.025 <- apply(qsim, 1, quantile, probs=0.025, na.rm=TRUE) q.975 <- apply(qsim, 1, quantile, probs=0.975, na.rm=TRUE) rr <- range(c(meanq,dat), na.rm=TRUE) dats <- if(fast) quantile(dat, probs=p, na.rm=TRUE) else sort(dat, na.last=TRUE) if(verbose) cat("..Done.\n") if(plot.it) { plot(meanq, dats, xlab="Mean quantile of simulations", ylab="data quantile", xlim=rr, ylim=rr, asp=1.0) abline(0,1) lines(meanq, q.025, lty=2, col="red") lines(meanq, q.975, lty=2, col="red") title(sub=paste("Residuals:", type)) } result <- list(x=meanq, y=dats, sdq=sdq, q.025=q.025, q.975=q.975, data=dat, sim=sim, xlim=rr, ylim=rr, xlab="Mean quantile of simulations", ylab="data quantile", rtype=type, nsim=nsim, fit=fit, expr=if(simulate.from.fit) NULL else deparse(expr), simulate.from.fit=simulate.from.fit) }, stop("Unrecognised option for \"style\"") ) # Throw out baggage if not wanted if(!saveall) { result$fit <- summary(fit, quick=TRUE) result$sim <- NULL } # reset npixel if(fast) spatstat.options(npixel=oldnpixel) # class(result) <- c("qqppm", class(result)) return(invisible(result)) } plot.qqppm <- function(x, ..., limits=TRUE) { stopifnot(inherits(x, "qqppm")) default.type <- if(length(x$x) > 150) "l" else "p" myplot <- function(object, xlab = object$xlab, ylab = object$ylab, xlim = object$xlim, ylim = object$ylim, asp = 1, type = default.type, ..., limits=TRUE) { plot(object$x, object$y, xlab = xlab, ylab = ylab, xlim = xlim, ylim = ylim, asp = asp, type = type, ...) abline(0, 1) if(limits) { if(!is.null(object$q.025)) lines(object$x, object$q.025, lty = 2, col="red") if(!is.null(object$q.975)) lines(object$x, object$q.975, lty = 2, col="red") } title(sub=paste("Residuals:", object$rtype)) } myplot(x, ..., limits=limits) return(invisible(x)) } print.qqppm <- function(x, ...) { stopifnot(inherits(x, "qqppm")) cat(paste("Q-Q plot of point process residuals ", "of type \`", x$rtype, "\'\n", "based on ", x$nsim, " simulations\n", sep="")) if(x$simulate.from.fit) { fit <- x$fit sumfit <- if(is.ppm(fit)) summary(fit, quick=TRUE) else if(inherits(fit, "summary.ppm")) fit else list(name="(unrecognised format)") cat(paste("\nSimulations from fitted model:", sumfit$name, "\n")) } else { cat("Simulations obtained by evaluating the following expression:\n") print(x$expr) } invisible(NULL) }