#
# interactions.R
#
# Works out which interaction is in force for a given point pattern
#
# $Revision: 1.26 $ $Date: 2021/12/29 00:24:51 $
#
#
impliedpresence <- function(tags, formula, df, extranames=character(0)) {
# Determines, for each row of the data frame df,
# whether the variable called tags[j] is required in the formula
stopifnot(is.data.frame(df))
stopifnot(inherits(formula, "formula"))
stopifnot(is.character(tags))
stopifnot(is.character(extranames))
# allvars <- variablesinformula(formula)
if(any(tags %in% names(df)))
stop(paste(sQuote("tags"),
"conflicts with the name of a column of",
sQuote("df")))
if(any(extranames %in% names(df)))
stop(paste(sQuote("extranames"),
"conflicts with the name of a column of",
sQuote("df")))
# answer is a matrix
nvars <- length(tags)
nrows <- nrow(df)
answer <- matrix(TRUE, nrows, nvars)
# expand data frame with zeroes for each tags and extranames
for(v in unique(c(tags, extranames)))
df[ , v] <- 0
# loop
for(i in seq(nrow(df))) {
# make a fake data frame for the formula
# using the data frame entries from row i
# (includes 0 values for all other variables)
pseudat <- df[i, , drop=FALSE]
# use this to construct a fake model matrix
mof0 <- model.frame(formula, pseudat)
mom0 <- model.matrix(formula, mof0)
for(j in seq(nvars)) {
# Reset the variable called tags[j] to 1
pseudatj <- pseudat
pseudatj[ , tags[j]] <- 1
# Now create the fake model matrix
mofj <- model.frame(formula, pseudatj)
momj <- model.matrix(formula, mofj)
# Compare the two matrices
answer[i,j] <- any(momj != mom0)
}
}
return(answer)
}
active.interactions <- function(object) {
stopifnot(inherits(object, "mppm"))
interaction <- object$Inter$interaction
iformula <- object$iformula
nenv <- new.env()
environment(iformula) <- nenv
random <- object$random
if(!is.null(random))
environment(random) <- nenv
itags <- object$Inter$itags
# The following are currently unused
# ninter <- object$Inter$ninter
# iused <- object$Inter$iused
# trivial <- object$Inter$trivial
# names of variables
dat <- object$data
datanames <- names(dat)
dfnames <- summary(dat)$dfnames
nondfnames <- datanames[!(datanames %in% dfnames)]
nondfnames <- union(nondfnames, c("x", "y"))
# extract data-frame values
dfdata <- as.data.frame(dat[, dfnames, drop=FALSE], warn=FALSE)
# determine which interaction(s) are in force
answer <- impliedpresence(itags, iformula, dfdata, nondfnames)
if(!is.null(random)) {
if("|" %in% all.names(random)) {
## hack since model.matrix doesn't handle "|" as desired
rnd <- gsub("|", "/", pasteFormula(random), fixed=TRUE)
random <- as.formula(rnd, env=environment(random))
}
answer2 <- impliedpresence(itags, random, dfdata, nondfnames)
answer <- answer | answer2
}
colnames(answer) <- names(interaction)
return(answer)
}
impliedcoefficients <- function(object, tag, new.coef=NULL) {
stopifnot(inherits(object, "mppm"))
stopifnot(is.character(tag) && length(tag) == 1)
fitobj <- object$Fit$FIT
Vnamelist <- object$Fit$Vnamelist
has.random <- object$Info$has.random
# Not currently used:
# fitter <- object$Fit$fitter
# interaction <- object$Inter$interaction
# ninteract <- object$Inter$ninteract
# trivial <- object$Inter$trivial
# iused <- object$Inter$iused
itags <- object$Inter$itags
if(!(tag %in% itags))
stop(paste("Argument", dQuote("tag"),
"is not one of the interaction names"))
# (0) Set up
# Identify the columns of the glm data frame
# that are associated with this interpoint interaction
vnames <- Vnamelist[[tag]]
if(!is.character(vnames))
stop("Internal error - wrong format for vnames")
# Check atomic type of each covariate
Moadf <- as.list(object$Fit$moadf)
islog <- sapply(Moadf, is.logical)
isnum <- sapply(Moadf, is.numeric)
isfac <- sapply(Moadf, is.factor)
# Interaction variables must be numeric or logical
if(any(bad <- !(isnum | islog)[vnames]))
stop(paste("Internal error: the",
ngettext(sum(bad), "variable", "variables"),
commasep(sQuote(vnames[bad])),
"should be numeric or logical"),
call.=FALSE)
# The answer is a matrix of coefficients,
# with one row for each point pattern,
# and one column for each vname
answer <- matrix(, nrow=object$npat, ncol=length(vnames))
colnames(answer) <- vnames
# (1) make a data frame of covariates
# Names of all columns in glm data frame
allnames <- names(Moadf)
# Extract the design covariates
df <- as.data.frame(object$data, warn=FALSE)
# Names of all covariates other than design covariates
othernames <- allnames[!(allnames %in% names(df))]
# Add columns in which all other covariates are set to 0, FALSE, etc
for(v in othernames) {
df[, v] <- if(isnum[[v]]) 0 else
if(islog[[v]]) FALSE else
if(isfac[[v]]) {
lev <- levels(Moadf[[v]])
factor(lev[1], levels=lev)
} else sort(unique(Moadf[[v]]))[1]
}
# (2) evaluate linear predictor
Coefs <- new.coef %orifnull% (if(!has.random) coef(fitobj) else fixef(fitobj))
suppressWarnings({
# eta0 <- predict(fitobj, newdata=df, type="link")
eta0 <- GLMpredict(fitobj, data=df, coefs=Coefs,
changecoef=TRUE, type="link")
})
# (3) for each vname in turn,
# set the value of the vname to 1 and predict again
for(j in seq_along(vnames)) {
vnj <- vnames[j]
df[[vnj]] <- 1
suppressWarnings({
# etaj <- predict(fitobj, newdata=df, type="link")
etaj <- GLMpredict(fitobj, data=df, coefs=Coefs,
changecoef=TRUE, type="link")
})
answer[ ,j] <- etaj - eta0
# set the value of this vname back to 0
df[[vnj]] <- 0
}
return(answer)
}
illegal.iformula <- local({
illegal.iformula <- function(ifmla, itags, dfvarnames) {
## THIS IS TOO STRINGENT!
## Check validity of the interaction formula.
## ifmla is the formula.
## itags is the character vector of interaction names.
## Check whether the occurrences of `itags' in `iformula' are valid:
## e.g. no functions applied to `itags[i]'.
## Returns NULL if legal, otherwise a character string
stopifnot(inherits(ifmla, "formula"))
stopifnot(is.character(itags))
## formula must not have a LHS
if(length(ifmla) > 2)
return("iformula must not have a left-hand side")
## variables in formula must be interaction tags or data frame variables
varsinf <- variablesinformula(ifmla)
if(!all(ok <- varsinf %in% c(itags, dfvarnames)))
return(paste(
ngettext(sum(!ok), "variable", "variables"),
paste(dQuote(varsinf[!ok]), collapse=", "),
"not allowed in iformula"))
## if formula uses no interaction tags, it's trivial
if(!any(itags %in% variablesinformula(ifmla)))
return(NULL)
## create terms object
tt <- attributes(terms(ifmla))
## extract all variables appearing in the formula
vars <- as.list(tt$variables)[-1]
## nvars <- length(vars)
varexprs <- lapply(vars, as.expression)
varstrings <- sapply(varexprs, paste)
## Each variable may be a name or an expression
v.is.name <- sapply(vars, is.name)
## a term may be an expression like sin(x), poly(x,y,degree=2)
v.args <- lapply(varexprs, all.vars)
## v.n.args <- sapply(v.args, length)
v.has.itag <- sapply(lapply(v.args, "%in%", x=itags), any)
## interaction tags may only appear as names, not in functions
if(any(nbg <- v.has.itag & !v.is.name))
return(paste("interaction tags may not appear inside a function:",
paste(dQuote(varstrings[nbg]), collapse=", ")))
## Interaction between two itags is not defined
## Inspect the higher-order terms
fax <- tt$factors
if(prod(dim(fax)) == 0)
return(NULL)
## rows are first order terms, columns are terms of order >= 1
fvars <- rownames(fax)
fterms <- colnames(fax)
fv.args <- lapply(fvars, variablesintext)
ft.args <- lapply(fterms, variables.in.term,
factors=fax, varnamelist=fv.args)
ft.itags <- lapply(ft.args, intersect, y=itags)
if(any(lengths(ft.itags) > 1))
return("Interaction between itags is not defined")
return(NULL)
}
variables.in.term <- function(term, factors, varnamelist) {
basis <- (factors[, term] != 0)
unlist(varnamelist[basis])
}
illegal.iformula
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.