\Header{tapply}{Apply a Function Over a ``Ragged'' Array}
\keyword{iteration}{tapply}
\keyword{category}{tapply}
\begin{Usage}
\begin{verbatim}
tapply(X, INDEX, FUN = NULL, simplify = TRUE, ...)
\end{verbatim}
\end{Usage}
\begin{Arguments}
\begin{ldescription}
\item[\texttt{X}] an atomic object, typically a vector.
\item[\texttt{INDEX}] list of factors, each of same length as \texttt{X}.
\item[\texttt{FUN}] the function to be applied.  In the case of functions like
\texttt{+}, \texttt{\%*\%}, etc., the function name must be quoted.  If
\texttt{FUN} is \texttt{NULL}, tapply returns a vector which can be used
to subscript the multi-way array \texttt{tapply} normally produces.
\item[\texttt{simplify}] If \texttt{FALSE}, \texttt{tapply} always returns an array
of mode \texttt{"list"}.  If \texttt{TRUE} (the default), then if
\texttt{FUN} always returns a scalar, \texttt{tapply} returns an array
with the mode of the scalar, and if the array would be one
dimensional the dimension is removed, to make it a vector.
\item[\texttt{...}] optional arguments to \texttt{FUN}.
\end{ldescription}
\end{Arguments}
\begin{Value}
When \texttt{FUN} is present, \texttt{tapply} calls \texttt{FUN} for each
cell that has any data in it.  If \texttt{FUN} returns a single atomic
value for each cell (e.g., functions \texttt{mean} or \texttt{var}), then
\texttt{tapply} returns a multi-way array containing the values.  The
array has the same number of dimensions as \texttt{INDEX} has
components; the number of levels in a dimension is the number of
levels (\texttt{nlevels(.)}) in the corresponding component of
\texttt{INDEX}.  This is a vector if \texttt{INDEX} has only one
component.

If \texttt{FUN} does not return a single atomic value, \texttt{tapply}
returns an array of mode \texttt{"\Link{list}"} whose components are the
values of the individual calls to \texttt{FUN}, i.e., the result is a
list with a \texttt{\Link{dim}} attribute.\end{Value}
\begin{SeeAlso}
\texttt{\Link{apply}}, \texttt{\Link{lapply}} with its version
\texttt{sapply}.\end{SeeAlso}
\begin{Examples}
\begin{ExampleCode}
groups <- as.factor(rbinom(32, n = 5, p = .4))
tapply(groups, groups, length) #- is almost the same as
table(groups)

n <- 17; fac <- factor(rep(1:3, len = n), levels = 1:5)
table(fac)
tapply(1:n, fac, sum)
tapply(1:n, fac, sum, simplify = FALSE) #- does not yet print okay
tapply(1:n, fac, range)			#- .. nor does this
tapply(1:n, fac, quantile)		#- ... or this

ind <- list(c(1, 2, 2), c("A", "A", "B"))
table(ind)
tapply(1:3, ind) #-> the split vector
tapply(1:3, ind, sum)
\end{ExampleCode}
\end{Examples}

