Skip to content

Commit 3040e58

Browse files
author
Steve Walker
committed
massage tests and add template approach to formula parsing
1 parent ada7525 commit 3040e58

14 files changed

+175
-123
lines changed

DESCRIPTION

+3-5
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ Description: The penalized least squares (PLS) and penalized iteratively
1010
in pure R. The purpose is to clarify how PLS and PIRLS work without having
1111
to read through C++ code, and as a sandbox for trying out modified versions
1212
of PLS and PIRLS.
13+
Depends:
14+
Matrix
1315
Suggests:
1416
minqa,
1517
mlmRev
1618
Imports:
17-
lme4,
18-
Matrix
19+
lme4
1920
License: GPL-2
20-
Collate:
21-
'pirls.R'
22-
'pls.R'

NAMESPACE

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1+
export(Zsection)
12
export(blockLambdat)
3+
export(mkLambdat)
4+
export(mkLind)
25
export(mkRanefRepresentation)
6+
export(mkRanefStructures)
7+
export(mkTemplate)
8+
export(mkTemplates)
9+
export(mkTheta)
10+
export(mkZt)
11+
export(mkZtSection)
312
export(pirls)
413
export(pls)
514
export(plsform)
6-
export(Zsection)
7-
importFrom(lme4,findbars)
8-
importFrom(lme4,nobars)
9-
importFrom(lme4,subbars)
10-
importFrom(Matrix,bdiag)
15+
export(rLmer)
1116
importFrom(Matrix,Cholesky)
1217
importFrom(Matrix,Diagonal)
18+
importFrom(Matrix,bdiag)
1319
importFrom(Matrix,rBind)
1420
importFrom(Matrix,sparse.model.matrix)
21+
importFrom(lme4,findbars)
22+
importFrom(lme4,nobars)
23+
importFrom(lme4,subbars)
1524
importMethodsFrom(Matrix,"%*%")
1625
importMethodsFrom(Matrix,crossprod)
1726
importMethodsFrom(Matrix,determinant)

R/pls.R

+22-19
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ NULL
1212
##' to read through C++ code, and as a sandbox for
1313
##' trying out modifications to PLS.
1414
##'
15-
##' @param X fixed effects design (model) matrix
15+
##' @param X fixed effects model matrix
1616
##' @param y response
1717
##' @param Zt transpose of the sparse model matrix for the random effects
1818
##' @param Lambdat upper triangular sparse Cholesky factor of the
@@ -109,14 +109,14 @@ pls <- function(X,y,Zt,Lambdat,thfun,weights,
109109
##'
110110
##' @return a \code{list} with:
111111
##' \itemize{
112-
##' \item \code{X} Fixed effects design (model) matrix
112+
##' \item \code{X} Fixed effects model matrix
113113
##' \item \code{y} Observed response vector
114114
##' \item \code{fr} Model frame
115115
##' \item \code{call} Matched call
116116
##' \item \code{REML} Logical indicating REML or not
117117
##' \item \code{weights} Prior weights or \code{NULL}
118118
##' \item \code{offset} Prior offset term or \code{NULL}
119-
##' \item \code{Zt} Transposed random effects design matrix
119+
##' \item \code{Zt} Transposed random effects model matrix
120120
##' \item \code{Lambdat} Transposed relative covariance factor
121121
##' \item \code{theta} Vector of covariance parameters
122122
##' \item \code{lower} Vector of lower bounds for \code{theta}
@@ -142,8 +142,9 @@ plsform <- function(formula, data, REML=TRUE, weights, offset, sparseX = FALSE,
142142
y = rho$y,
143143
fr = fr, call = mc,
144144
REML = as.logical(REML)[1]),
145-
if (is.null(wts <- model.weights(fr))) wts else list(weights=wts),
146-
if (is.null(off <- model.offset(fr))) off else list(offset=off),
145+
#if (is.null(wts <- model.weights(fr))) wts else list(weights=wts),
146+
#if (is.null(off <- model.offset(fr))) off else list(offset=off),
147+
list(weights = rho$weights), list(offset = rho$offset),
147148
mkRanefRepresentation(lapply(rr, function(t) as.factor(eval(t[[3]], fr))),
148149
lapply(rr, function(t)
149150
model.matrix(eval(substitute( ~ foo, list(foo = t[[2]]))), fr))))
@@ -155,8 +156,8 @@ initializeResp <- function(fr, REML, family){
155156
if(!inherits(family,"family")) family <- family()
156157
y <- model.response(fr)
157158
### Why consider there here? They are handled in plsform.
158-
#offset <- model.offset(fr)
159-
#weights <- model.weights(fr)
159+
# offset <- model.offset(fr)
160+
# weights <- model.weights(fr)
160161
n <- nrow(fr)
161162
etastart_update <- model.extract(fr, "etastart")
162163
if(length(dim(y)) == 1) {
@@ -172,15 +173,15 @@ initializeResp <- function(fr, REML, family){
172173
if (!is.null(REML)) rho$REML <- REML
173174
rho$etastart <- fr$etastart
174175
rho$mustart <- fr$mustart
175-
#if (!is.null(offset)) {
176-
# if (length(offset) == 1L) offset <- rep.int(offset, n)
177-
# stopifnot(length(offset) == n)
178-
# rho$offset <- unname(offset)
179-
#} else rho$offset <- rep.int(0, n)
180-
#if (!is.null(weights)) {
181-
# stopifnot(length(weights) == n, all(weights >= 0))
182-
# rho$weights <- unname(weights)
183-
#} else rho$weights <- rep.int(1, n)
176+
if (!is.null(offset <- model.offset(fr))) {
177+
if (length(offset) == 1L) offset <- rep.int(offset, n)
178+
stopifnot(length(offset) == n)
179+
rho$offset <- unname(offset)
180+
} else rho$offset <- rep.int(0, n)
181+
if (!is.null(weights <- model.weights(fr))) {
182+
stopifnot(length(weights) == n, all(weights >= 0))
183+
rho$weights <- unname(weights)
184+
} else rho$weights <- rep.int(1, n)
184185
stopifnot(inherits(family, "family"))
185186
rho$nobs <- n
186187
eval(family$initialize, rho)
@@ -202,11 +203,11 @@ mkMFCall <- function(mc, form, nobars=FALSE) {
202203
mc
203204
}
204205

205-
##' Create a section of a transposed random effects design matrix
206+
##' Create a section of a transposed random effects model matrix
206207
##'
207208
##' @param grp Grouping factor for a particular random effects term.
208209
##' @param mm Dense model matrix for a particular random effects term.
209-
##' @return Section of a random effects design matrix corresponding to a
210+
##' @return Section of a random effects model matrix corresponding to a
210211
##' particular term.
211212
##' @export
212213
##' @examples
@@ -342,6 +343,8 @@ blockLambdat <- function(nl, nc) {
342343
}
343344

344345

346+
347+
345348
##' Make random effects representation
346349
##'
347350
##' Create all of the elements required to specify the random-effects
@@ -363,7 +366,7 @@ blockLambdat <- function(nl, nc) {
363366
##' @return A \code{list} with:
364367
##' \itemize{
365368
##' \item \code{Lambdat} Transformed relative covariance factor
366-
##' \item \code{Zt} Transformed random effects design matrix
369+
##' \item \code{Zt} Transformed random effects model matrix
367370
##' \item \code{theta} Vector of covariance parameters
368371
##' \item \code{lower} Vector of lower bounds on the covariance parameters
369372
##' \item \code{upper} Vector of upper bounds on the covariance parameters

R/templateApproach.R

+40-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,39 @@
1+
##' Random lmer-type model simulation
2+
##' @export
3+
rLmer <- function(grp, mmRE, mmFE) message("not yet written")
4+
5+
6+
##' Make random effects structures
7+
##' @export
8+
mkRanefStructures <- function(grp, mm){
9+
# checking things are OK
10+
if(!is.list(grp)) grp <- list(grp)
11+
if(!is.list(mm)) mm <- list(mm)
12+
grp <- lapply(grp, as.factor)
13+
14+
15+
nl <- sapply(grp, nlevels) # number of grouping factor levels per term
16+
nc <- sapply(mm, ncol) # number of model matrix columns per term
17+
templates <- mkTemplates(nc) # templates for relative covariance factor
18+
theta <- mkTheta(templates)
19+
20+
list( Zt = mkZt(grp, mm),
21+
Lambdat = mkLambdat(templates, nl),
22+
Lind = mkLind(nl, nc),
23+
theta = theta,
24+
lower = ifelse(theta, 0, -Inf), # lower and
25+
upper = rep(Inf, length(theta)) # upper bounds on theta parameters
26+
)
27+
}
28+
29+
130
##' Create a section of a transposed random effects model matrix
231
##'
332
##' @param grp Grouping factor for a particular random effects term.
433
##' @param mm Dense model matrix for a particular random effects term.
534
##' @return Section of a random effects design matrix corresponding to a
635
##' particular term.
36+
##' @export
737
##' @examples
838
##' ## consider a term (x | g) with:
939
##' ## number of observations, n = 6
@@ -23,16 +53,17 @@ mkZtSection <- function(grp,mm) {
2353
}
2454

2555
##' Make transposed random-effects model matrix
56+
##' @export
2657
mkZt <- function(grp,mm){
27-
ZtSections <- mapply(mkZtSection, grp, mm)
28-
rBind(ZtSections)
58+
ZtSections <- mapply(mkZtSection, grp, mm, SIMPLIFY=FALSE)
59+
do.call(rBind, ZtSections)
2960
}
3061

31-
3262
##' Make a single template for a relative covariance factor
3363
##'
3464
##' @param nc Number of columns in a dense model matrix for a particular
3565
##' random effects term
66+
##' @export
3667
##' @examples
3768
##' mkTemplate(5)
3869
mkTemplate <- function(nc){
@@ -48,9 +79,11 @@ mkTemplate <- function(nc){
4879
}
4980

5081
##' Make list of templates for relative covariance factor
82+
##' @export
5183
mkTemplates <- function(nc) lapply(nc, mkTemplate)
5284

5385
##' Make vector of indices giving the mapping from theta to Lambdat
86+
##' @export
5487
mkLind <- function(nl, nc){
5588
# number of thetas per term (i.e. number
5689
# of elements in the upper triangle of
@@ -69,17 +102,18 @@ mkLind <- function(nl, nc){
69102
}
70103

71104
##' Make initial relative covariance factor from list of templates
105+
##' @export
72106
mkLambdat <- function(templates, nl){
73107
# repeat templates once for each level
74-
repTemplates <- rep(templates, nl)
108+
templateList <- rep(templates, nl)
75109
# return Lambdat by putting blocks
76110
# together along the diagonal
77-
.bdiag(repTemplates)
111+
.bdiag(templateList)
78112
}
79113

80114
##' Make initial theta from list of templates
115+
##' @export
81116
mkTheta <- function(templates){
82117
thetas <- lapply(templates, slot, "x")
83118
unlist(thetas)
84119
}
85-

man/Zsection.Rd

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
\name{Zsection}
22
\alias{Zsection}
3-
\title{Create a section of a transposed random effects design matrix}
3+
\title{Create a section of a transposed random effects model matrix}
44
\usage{
5-
Zsection(grp, mm)
5+
Zsection(grp, mm)
66
}
77
\arguments{
88
\item{grp}{Grouping factor for a particular random
@@ -12,11 +12,12 @@
1212
effects term.}
1313
}
1414
\value{
15-
Dense section of a random effects design matrix
15+
Section of a random effects model matrix corresponding to a
16+
particular term.
1617
}
1718
\description{
18-
Create a section of a transposed random effects design
19-
matrix
19+
Create a section of a transposed random effects model
20+
matrix
2021
}
2122
\examples{
2223
## consider a term (x | g) with:

man/blockLambdat.Rd

+9-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
\alias{blockLambdat}
33
\title{Create digonal block on transposed relative covariance factor}
44
\usage{
5-
blockLambdat(nl, nc)
5+
blockLambdat(nl, nc)
66
}
77
\arguments{
88
\item{nl}{Number of levels in a grouping factor for a
@@ -14,17 +14,16 @@
1414
the \code{mm} argument in \code{\link{Zsection}}).}
1515
}
1616
\value{
17-
A \code{list} with: \itemize{ \item the block \item
18-
ititial values of theta for the block \item lower bounds
19-
on these initial theta values \item a function that
20-
updates the block given the section of theta for this
21-
block }
17+
A \code{list} with: \itemize{ \item the block \item ititial
18+
values of theta for the block \item lower bounds on these
19+
initial theta values \item a function that updates the
20+
block given the section of theta for this block }
2221
}
2322
\description{
24-
Each random-effects term is represented by diagonal block
25-
on the transposed relative covariance factor.
26-
\code{blockLambdat} creates such a block, and returns
27-
related information along with it.
23+
Each random-effects term is represented by diagonal block
24+
on the transposed relative covariance factor.
25+
\code{blockLambdat} creates such a block, and returns
26+
related information along with it.
2827
}
2928
\examples{
3029
(l <- blockLambdat(2, 3))

man/mkRanefRepresentation.Rd

+20-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
\alias{mkRanefRepresentation}
33
\title{Make random effects representation}
44
\usage{
5-
mkRanefRepresentation(grps, mms)
5+
mkRanefRepresentation(grps, mms)
66
}
77
\arguments{
88
\item{grps}{List of factor vectors of length n indicating
@@ -13,29 +13,28 @@
1313
corresponds to a random effects term.}
1414
}
1515
\value{
16-
A \code{list} with: \itemize{ \item \code{Lambdat}
17-
Transformed relative covariance factor \item \code{Zt}
18-
Transformed random effects design matrix \item
19-
\code{theta} Vector of covariance parameters \item
20-
\code{lower} Vector of lower bounds on the covariance
21-
parameters \item \code{upper} Vector of upper bounds on
22-
the covariance parameters \item \code{thfun} A function
23-
that maps \code{theta} onto the non-zero elements of
24-
\code{Lambdat} }
16+
A \code{list} with: \itemize{ \item \code{Lambdat}
17+
Transformed relative covariance factor \item \code{Zt}
18+
Transformed random effects model matrix \item \code{theta}
19+
Vector of covariance parameters \item \code{lower} Vector
20+
of lower bounds on the covariance parameters \item
21+
\code{upper} Vector of upper bounds on the covariance
22+
parameters \item \code{thfun} A function that maps
23+
\code{theta} onto the non-zero elements of \code{Lambdat} }
2524
}
2625
\description{
27-
Create all of the elements required to specify the
28-
random-effects structure of a mixed effects model.
26+
Create all of the elements required to specify the
27+
random-effects structure of a mixed effects model.
2928
}
3029
\details{
31-
The basic idea of this function is to call
32-
\code{\link{Zsection}} and \code{\link{blockLambdat}}
33-
once for each random effects term (ie. each list element
34-
in \code{grps} and \code{mms}). The results of
35-
\code{\link{Zsection}} for each term are \code{rBind}ed
36-
together. The results of \code{\link{blockLambdat}} are
37-
\code{bdiag}ed together, unless all terms have only a
38-
single column ('predictor') in which case a diagonal
39-
matrix is created directly.
30+
The basic idea of this function is to call
31+
\code{\link{Zsection}} and \code{\link{blockLambdat}} once
32+
for each random effects term (ie. each list element in
33+
\code{grps} and \code{mms}). The results of
34+
\code{\link{Zsection}} for each term are \code{rBind}ed
35+
together. The results of \code{\link{blockLambdat}} are
36+
\code{bdiag}ed together, unless all terms have only a
37+
single column ('predictor') in which case a diagonal matrix
38+
is created directly.
4039
}
4140

0 commit comments

Comments
 (0)