apply
Apply a Function to Sections of an Array
Description
Returns a vector or array by applying a specified function to
sections of an array.
Usage
apply(X, MARGIN, FUN, ...)
Arguments
X |
an array or a matrix.
Other types are converted with as.matrix (if dim(X)
has two elements)
or as.array (otherwise).
Missing values (NAs) are allowed
if FUN accepts them.
|
MARGIN |
A vector of integers or character strings over which the function is to be applied.
For example, if X is a matrix, then
MARGIN=1 indicates rows
and MARGIN=2 indicates columns.
If MARGIN is a vector of character strings, then those character strings should be a subset of names(dimnames(X)).
If MARGIN is a vector of integers, then the integers should a subset of seq_along(dim(X)).
Note that MARGIN tells which dimensions
of X are retained in the result.
|
FUN |
a function to be applied to the specified array sections,
or a character string giving the name of the function.
The character form is necessary only for functions with unusual
names, such as "%*%".
|
... |
any arguments to FUN.
The arguments are passed unchanged to each call of FUN
and include their names.
|
Details
The arguments to apply have unusual
upper-case names, so they do not conflict with names
that might be used by FUN.
A subarray is extracted from X for
each combination of the levels of the subscripts
named in MARGIN.
The function FUN is invoked
for each of these subarrays,
and the results (if any) are concatenated into a new array.
Each section of the input array is passed as the first argument
to an invocation of FUN.
It is passed without a keyword modifier,
so, by attaching keywords in ...,
it is possible to make the array section correspond to any argument
of FUN. See the examples for an illustration.
In one example below, z is a 4-way array
with the dimension vector (2,3,4,5).
The expression apply(z, c(1,3), sum) computes
the 2 by 4 matrix obtained by summing over the second and fourth
extents of z.
That is, sum is called 8 times,
each time on 15 values.
The sorting examples below show the difference
between row and column operations
when the result returned by FUN is a vector.
The returned value is the first dimension of the result,
hence the transpose (via the t or more general aperm
function) is necessary with row sorts.
If the results returned by FUN are
of different dimensions or lengths,
apply returns a list rather than an array,
as shown in the last example below.
Value
- If each call to FUN returns a vector
of length N,
and N>1, apply returns an array
of dimension c(N, dim(X)[MARGIN]).
- If N==1 and MARGIN has length > 1,
apply returns an array of dimension dim(X)[MARGIN].
- Otherwise, apply returns a vector.
Note
- The functions lapply
and sapply apply a function to each element
of a list.
- The function tapply applies a function
to a ragged array defined by categories.
- The sweep function for arrays
is similar to apply.
To perform explicit looping, use
for,
while,
or
repeat.
The functions colSums, colMeans, rowSums, and
rowMeans provide common operations, for which you do not need
apply.
If X is a data frame, then X
is coerced to a matrix using as.matrix.
This can give surprising results.
If there are any factor columns then as.matrix
converts all columns to character.
For more predictable results, operate on columns with
sapply.
See Also
Examples
# 25% trimmed column means. The result is a vector of length ncol(x).
x <- matrix(round(sin(20:1),2), ncol=5, dimnames=list(Subject=NULL,Quality=paste0("q",1:5)))
apply(x, 2, mean, trim=.25)
apply(x, "Quality", mean, trim=.25)
apply(matrix(1:4,nrow=2),2,function(x,y) x^y, 2)
apply(matrix(1:4,nrow=2),2,function(x,y) x^y, x=2)
# Sort the columns of x.
apply(x, "Quality", sort)
# Transpose the result of row sort.
t(apply(x, "Subject", sort))
# This apply command returns the equivalent of
# z[,1,,1] + z[,1,,2] + z[,1,,3] + z[,1,,4] + z[,1,,5] +
# z[,2,,1] + z[,2,,2] + z[,2,,3] + z[,2,,4] + z[,2,,5] +
# z[,3,,1] + z[,3,,2] + z[,3,,3] + z[,3,,4] + z[,3,,5]
z <- array(c(1:24, 101:124, 201:224, 301:324, 401:424), dim=c(2,3,4,5))
apply(z, c(1, 3), sum)
# This command returns a list, since the lengths of
# results are not equal.
apply(matrix(1:12, nrow=4), 2, function(x) which(x <= 6))