Raw File
qqplotppm.R
#
#    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)
}
back to top