Fast Row/Column Arithmetic for Matrix-Like Objects
Fast operators to perform row- or column-wise replacing and sweeping operations of vectors on matrices, data frames, lists.
## Perform the operation with v and each row of X X %rr% v # Replace rows of X with v X %r+% v # Add v to each row of X X %r-% v # Subtract v from each row of X X %r*% v # Multiply each row of X with v X %r/% v # Divide each row of X by v ## Perform the operation with v and each column of X X %cr% v # Replace columns of X with v X %c+% v # Add v to each column of X X %c-% v # Subtract v from each column of X X %c*% v # Multiply each column of X with v X %c/% v # Divide each column of X by v
X |
a vector, matrix, data frame or list like object (with rows (r) columns (c) matching |
v |
a suitable atomic vector. If |
With a matrix or data frame X
, the default behavior of R when calling X op v
(such as multiplication X * v
) is to perform the operation of v
with each column of X
. The equivalent operation is performed by X %cop% v
, with the difference that it computes significantly faster if X
is a data frame / list. A more complex but frequently required task is to perform an operation with v
on each row of X
. This is provided based on efficient C++ code by the %rop%
set of functions, e.g. X %r*% v
efficiently multiplies v
to each row of X
.
X
where the operation with v
was performed on each row or column. All attributes of X
are preserved.
Computations and Output: These functions are all quite simple, they only work with X
on the LHS i.e. v %op% X
will likely fail. The row operations are simple wrappers around TRA
which provides more operations including grouped replacing and sweeping (where v
would be a matrix or data frame with less rows than X
being mapped to the rows of X
by grouping vectors). One consequence is that just like TRA
, row-wise mathematical operations (+, -, *, /) always yield numeric output, even if both X
and v
may be integer. This is different for column- operations which depend on base R and may also preserve integer data.
Rules of Arithmetic: Since these operators are defined as simple infix functions, the normal rules of arithmetic are not respected. So a %c+% b %c*% c
evaluates as (a %c+% b) %c*% c
. As with all chained infix operations, they are just evaluated sequentially from left to right.
Performance Notes: For Fast Statistical Functions, using fmedian(X, TRA = "-")
will be a tiny bit faster than X %r-% fmedian(X)
. Also use fwithin(X)
for fast centering using the mean, and fscale(X)
for fast scaling and centering or mean-preserving scaling.
## Using data frame's / lists v <- mtcars$cyl mtcars %cr% v mtcars %c-% v mtcars %r-% seq_col(mtcars) mtcars %r-% lapply(mtcars, quantile, 0.28) mtcars %c*% 5 # Significantly faster than mtcars * 5 mtcars %c*% mtcars # Significantly faster than mtcars * mtcars ## Using matrices X <- qM(mtcars) X %cr% v X %c-% v X %r-% dapply(X, quantile, 0.28) ## Chained Operations library(magrittr) mtcars %>% fwithin %r-% rnorm(11) %c*% 5 %>% tfm(mpg = fsum(mpg)) %>% qsu
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.