1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
|
\name{indMatrix-class}
\title{Index Matrices}
%
\docType{class}
\keyword{array}
\keyword{classes}
%
\alias{indMatrix-class}
%
\alias{!,indMatrix-method}
\alias{-,indMatrix,missing-method}
\alias{Math,indMatrix-method}
\alias{Summary,indMatrix-method}
\alias{coerce,indMatrix,pMatrix-method}
\alias{coerce,list,indMatrix-method}
\alias{coerce,matrix,indMatrix-method}
\alias{coerce,numeric,indMatrix-method}
\alias{determinant,indMatrix,logical-method}
\alias{diag,indMatrix-method}
\alias{diag<-,indMatrix-method}
\alias{log,indMatrix-method}
\alias{t,indMatrix-method}
\alias{which,indMatrix-method}
%
\description{
The \code{indMatrix} class is the class of row and column
\emph{index} matrices, stored as 1-based integer index vectors.
A row (column) index matrix is a matrix whose rows (columns)
are standard unit vectors. Such matrices are useful
when mapping observations to discrete sets of covariate values.
Multiplying a matrix on the left by a row index matrix is
equivalent to indexing its rows, i.e., sampling the rows
\dQuote{with replacement}. Analogously, multiplying a matrix
on the right by a column index matrix is equivalent to
indexing its columns. Indeed, such products are implemented in
\pkg{Matrix} as indexing operations; see \sQuote{Details} below.
A matrix whose rows \emph{and} columns are standard unit vectors
is called a \emph{permutation} matrix. This special case is
designated by the \code{\linkS4class{pMatrix}} class, a direct
subclass of \code{indMatrix}.
}
\section{Objects from the Class}{
Objects can be created explicitly with calls of the form
\code{new("indMatrix", ...)}, but they are more commonly created
by coercing 1-based integer index vectors, with calls of the
form \code{as(., "indMatrix")}; see \sQuote{Methods} below.
}
\section{Slots}{
\describe{
\item{\code{margin}}{an integer, either 1 or 2, specifying
whether the matrix is a row (1) or column (2) index.}
\item{\code{perm}}{a 1-based integer index vector, i.e.,
a vector of length \code{Dim[margin]} with elements
taken from \code{1:Dim[1+margin\%\%2]}.}
\item{\code{Dim},\code{Dimnames}}{inherited from virtual
superclass \code{\linkS4class{Matrix}}.}
}
}
\section{Extends}{
Classes \code{"\linkS4class{sparseMatrix}"} and
\code{"\linkS4class{generalMatrix}"}, directly.
}
\section{Methods}{
\describe{
\item{\code{\%*\%}}{\code{signature(x = "indMatrix", y = "Matrix")}
and others listed by \code{showMethods("\%*\%", classes = "indMatrix")}:
matrix products implemented where appropriate as indexing operations.}
\item{\code{coerce}}{\code{signature(from = "numeric", to = "indMatrix")}:
supporting typical \code{indMatrix} construction from
a vector of positive integers. Row indexing is assumed.}
\item{\code{coerce}}{\code{signature(from = "list", to = "indMatrix")}:
supporting \code{indMatrix} construction for row \emph{and}
column indexing, including index vectors of length 0 and
index vectors whose maximum is less than the number of rows
or columns being indexed.}
\item{\code{coerce}}{\code{signature(from = "indMatrix", to = "matrix")}:
coercion to a traditional \code{\link{matrix}} of \link{logical} type,
with \code{FALSE} and \code{TRUE} in place of 0 and 1.}
\item{\code{t}}{\code{signature(x = "indMatrix")}:
the transpose, which is an \code{indMatrix} with identical
\code{perm} but opposite \code{margin}.}
\item{\code{rowSums},\code{rowMeans},\code{colSums},\code{colMeans}}{\code{signature(x = "indMatrix")}:
row and column sums and means.}
\item{\code{rbind2},\code{cbind2}}{\code{signature(x = "indMatrix", y = "indMatrix")}:
row-wise catenation of two row index matrices with equal numbers
of columns and column-wise catenation of two column index matrices
with equal numbers of rows.}
\item{kronecker}{\code{signature(X = "indMatrix", Y = "indMatrix")}:
Kronecker product of two row index matrices or two column index
matrices, giving the row or column index matrix corresponding to
their \dQuote{interaction}.}
}
}
\author{Fabian Scheipl at \file{uni-muenchen.de}, building on the existing class
\code{\linkS4class{pMatrix}} after a nice hike's conversation with
Martin Maechler. Methods for \code{\link{crossprod}(x, y)} and
\code{\link{kronecker}(x, y)} with both arguments inheriting from
\code{indMatrix} were made considerably faster thanks to a suggestion
by Boris Vaillant. Diverse tweaks by Martin Maechler and
Mikael Jagan, notably the latter's implementation of \code{margin},
prior to which the \code{indMatrix} class was designated only for
row index matrices.
}
\details{
The transpose of an index matrix is an index matrix with identical
\code{perm} but opposite \code{margin}. Hence the transpose of a
row index matrix is a column index matrix, and vice versa.
The cross product of a row index matrix \code{R} and itself is a
diagonal matrix whose diagonal entries are the the number of entries
in each column of \code{R}.
Given a row index matrix \code{R} with \code{perm} slot \code{p},
a column index matrix \code{C} with \code{perm} slot \code{q},
and a matrix \code{M} with conformable dimensions, we have
\tabular{lclcl}{
\eqn{R M} \tab = \tab \code{R \%*\% M} \tab = \tab \code{M[p, ]}\cr
\eqn{M C} \tab = \tab \code{M \%*\% C} \tab = \tab \code{M[, q]}\cr
\eqn{C'M} \tab = \tab \code{crossprod(C, M)} \tab = \tab \code{M[q, ]}\cr
\eqn{MR'} \tab = \tab \code{tcrossprod(M, R)} \tab = \tab \code{M[, p]}\cr
\eqn{R'R} \tab = \tab \code{crossprod(R)} \tab = \tab \code{Diagonal(x=tabulate(p, ncol(R)))}\cr
\eqn{CC'} \tab = \tab \code{tcrossprod(C)} \tab = \tab \code{Diagonal(x=tabulate(q, nrow(C)))}
}
Operations on index matrices that result in index matrices will
accordingly return an \code{indMatrix}. These include products
of two column index matrices and (equivalently) column-indexing
of a column index matrix (when dimensions are not dropped).
Most other operations on \code{indMatrix} treat them as sparse
nonzero pattern matrices (i.e., inheriting from virtual class
\code{\linkS4class{nsparseMatrix}}). Hence vector-valued subsets
of \code{indMatrix}, such as those given by \code{\link{diag}},
are always of type \code{"\link{logical}"}.
}
\seealso{
Subclass \code{\linkS4class{pMatrix}} of permutation matrices,
a special case of index matrices; virtual class
\code{\linkS4class{nMatrix}} of nonzero pattern matrices,
and its subclasses.
}
\examples{
p1 <- as(c(2,3,1), "pMatrix")
(sm1 <- as(rep(c(2,3,1), e=3), "indMatrix"))
stopifnot(all(sm1 == p1[rep(1:3, each=3),]))
## row-indexing of a <pMatrix> turns it into an <indMatrix>:
class(p1[rep(1:3, each=3),])
set.seed(12) # so we know '10' is in sample
## random index matrix for 30 observations and 10 unique values:
(s10 <- as(sample(10, 30, replace=TRUE),"indMatrix"))
## Sample rows of a numeric matrix :
(mm <- matrix(1:10, nrow=10, ncol=3))
s10 \%*\% mm
set.seed(27)
IM1 <- as(sample(1:20, 100, replace=TRUE), "indMatrix")
IM2 <- as(sample(1:18, 100, replace=TRUE), "indMatrix")
(c12 <- crossprod(IM1,IM2))
## same as cross-tabulation of the two index vectors:
stopifnot(all(c12 - unclass(table(IM1@perm, IM2@perm)) == 0))
# 3 observations, 4 implied values, first does not occur in sample:
as(2:4, "indMatrix")
# 3 observations, 5 values, first and last do not occur in sample:
as(list(2:4, 5), "indMatrix")
as(sm1, "nMatrix")
s10[1:7, 1:4] # gives an "ngTMatrix" (most economic!)
s10[1:4, ] # preserves "indMatrix"-class
I1 <- as(c(5:1,6:4,7:3), "indMatrix")
I2 <- as(7:1, "pMatrix")
(I12 <- rbind(I1, I2))
stopifnot(is(I12, "indMatrix"),
identical(I12, rbind(I1, I2)),
colSums(I12) == c(2L,2:4,4:2))
}
|