R: Apply Functions Over Array Margins

apply {base} | R Documentation

## Apply Functions Over Array Margins

### Description

Returns a vector or array or list of values obtained by applying a function to margins of an array or matrix.

### Usage

    apply(X, MARGIN, FUN, ...)

### Arguments

`X` | an array, including a matrix.
`MARGIN` | a vector giving the subscripts which the function will be applied over. E.g., for a matrix `1` indicates rows, `2` indicates columns, `c(1, 2)` indicates rows and columns. Where `X` has named dimnames, it can be a character vector selecting dimension names.
`FUN` | the function to be applied: see ‘Details’. In the case of functions like `+`, `%*%`, etc., the function name must be backquoted or quoted.
`...` | optional arguments to `FUN`.

### Details

If `X` is not an array but an object of a class with a non-null `dim` value (such as a data frame), `apply` attempts to coerce it to an array via `as.matrix` if it is two-dimensional (e.g., a data frame) or via `as.array`.

`FUN` is found by a call to `match.fun` and typically is either a function or a symbol (e.g., a backquoted name) or a character string specifying a function to be searched for from the environment of the call to `apply`.

Arguments in `...` cannot have the same name as any of the other arguments, and care may be needed to avoid partial matching to `MARGIN` or `FUN`. In general-purpose code it is good practice to name the first three arguments if `...` is passed through: this both avoids partial matching to `MARGIN` or `FUN` and ensures that a sensible error message is given if arguments named `X`, `MARGIN` or `FUN` are passed through `...`.

### Value

If each call to `FUN` returns a vector of length `n`, then `apply` returns an array of dimension `c(n, dim(X)[MARGIN])` if `n > 1`. If `n` equals `1`, `apply` returns a vector if `MARGIN` has length 1 and an array of dimension `dim(X)[MARGIN]` otherwise. If `n` is `0`, the result has length 0 but not necessarily the ‘correct’ dimension.

If the calls to `FUN` return vectors of different lengths, `apply` returns a list of length `prod(dim(X)[MARGIN])` with `dim` set to `MARGIN` if this has length greater than one.

In all cases the result is coerced by `as.vector` to one of the basic vector types before the dimensions are set, so that (for example) factor results will be coerced to a character array.

### References

Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.

### See Also

`lapply` and there, `simplify2array`; `tapply`, and convenience functions `sweep` and `aggregate`.

### Examples

    ## Compute row and column sums for a matrix:
    x <- cbind(x1 = 3, x2 = c(4:1, 2:5))
    dimnames(x)[[1]] <- letters[1:8]
    apply(x, 2, mean, trim = .2)
    col.sums <- apply(x, 2, sum)
    row.sums <- apply(x, 1, sum)
    rbind(cbind(x, Rtot = row.sums), Ctot = c(col.sums, sum(col.sums)))

    stopifnot( apply(x, 2, is.vector))

    ## Sort the columns of a matrix
    apply(x, 2, sort)

    ## keeping named dimnames
    names(dimnames(x)) <- c("row", "col")
    x3 <- array(x, dim = c(dim(x),3),
    	    dimnames = c(dimnames(x), list(C = paste0("cop.",1:3))))
    identical(x,  apply( x,  2,  identity))
    identical(x3, apply(x3, 2:3, identity))

    ##- function with extra args:
    cave <- function(x, c1, c2) c(mean(x[c1]), mean(x[c2]))
    apply(x, 1, cave,  c1 = "x1", c2 = c("x1","x2"))

    ma <- matrix(c(1:4, 1, 6:8), nrow = 2)
    ma
    apply(ma, 1, table)  #--> a list of length 2
    apply(ma, 1, stats::quantile) # 5 x n matrix with rownames

    stopifnot(dim(ma) == dim(apply(ma, 1:2, sum)))

    ## Example with different lengths for each call
    z <- array(1:24, dim = 2:4)
    zseq <- apply(z, 1:2, function(x) seq_len(max(x)))
    zseq         ## a 2 x 3 matrix
    typeof(zseq) ## list
    dim(zseq) ## 2 3
    zseq[1,]
    apply(z, 3, function(x) seq_len(max(x)))
    # a list without a dim attribute

[Package base version 4.0.5 Index]