Writing Custom Functions for matsbyname
Author: Matthew Kuperus Heun
Date: 2026-01-29

# Writing Custom Functions for `matsbyname`

#### Matthew Kuperus Heun

#### 2026-01-29

## Introduction

The `matsbyname` package provides many useful functions for "by name" manipulation of matrices, lists of matrices, and matrices in columns of data frames. However, the built-in functions may not cover all possible needs. `matsbyname` provides three functions for these situations:

Function | Purpose
--- | ---
`unaryapply_byname` | apply a unary function to a single matrix, a list of matrices, or a column of matrices in a data frame
`elementapply_byname` | apply a unary function to a single element of a matrix or a column of matrices in a data frame
`binaryapply_byname` | apply a binary function to two matrices or Map a binary function across two lists of matrices or two columns of matrices in a data frame
`cumapply_byname` | apply a binary function cumulatively to a single list of matrices or a column of matrices in a data frame

## How the `*apply_byname` functions work

The `*apply_byname` functions have several arguments.

Argument | Description
--- | ---
`FUN` | a unary function in the case of `unaryapply_byname`, a binary function (that may also accept a single argument) in the case of `binaryapply_byname`, and a binary function (that must also accept only a single argument) in the case of `cumapply_byname`
`a` | a matrix, a list or matrices, or a column of matrices in a data frame
`b` | a matrix, a list or matrices, or a column of matrices in a data frame
`.FUNdots` | a named list of arguments to be passed to `FUN`
`rowcoltypes` | tells what to do with row and column types
`match_type` | tells how row and column types of `a` and `b` arguments must be matched
`.organize` | tells whether to automatically complete `a` and `b` relative to each other and sort the rows and columns of the completed matrices

`FUN` is mapped as expected over `a` (in the case of `unaryapply_byname`, `elementapply_byname`, and `cumapply_byname`) or over `a` and `b` (in the case of `binaryapply_byname`). `FUN` should assume that its `a` and/or `b` arguments are single numbers or matrices; `*apply_byname` handles all mapping across lists. The following sections describe each `*apply_byname` function.

## `unaryapply_byname`

`unaryapply_byname` applies `FUN` to a single matrix, a list of matrices, or (if used with `dplyr::mutate()`) a column in a data frame that contains matrices. The `rowcoltypes` argument must be one of the following:

`rowcoltypes` value | Behaviour
--- | ---
`"all"` | transfer both row and column types of directly to output (the default)
`"transpose"` | rowtype of becomes coltype of output; coltype of becomes rowtype of output
`"row"` | rowtype of becomes both rowtype and coltype of output
`"col"` | coltype of becomes both rowtype and coltype of output
`"none"` | rowtype and coltype not set by this function; will set rowtype and coltype

A simple example follows.

    U <- matrix(1:4, ncol = 2, dimnames = list(c("p1", "p2"), c("i1", "i2"))) %>%
      setrowtype("Products") %>% setcoltype("Industries")
    U

    ##    i1 i2
    ## p1  1  3
    ## p2  2  4
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

    difference_byname(0, U)

    ##    i1 i2
    ## p1 -1 -3
    ## p2 -2 -4
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

    unaryapply_byname(`-`, U)

    ##    i1 i2
    ## p1 -1 -3
    ## p2 -2 -4
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

## `elementapply_byname`

`elementapply_byname` applies `FUN` to a single matrix, a list of matrices, or (if used with `dplyr::mutate()`) a column in a data frame that contains matrices.

A simple example follows.

    divide <- function(x, divisor){
      x/divisor
    }
    m <- matrix(c(1:4), nrow = 2, ncol = 2, dimnames = list(c("r1", "r2"), c("c1", "c2"))) %>%
      setrowtype("row") %>% setcoltype("col")
    m

    ##    c1 c2
    ## r1  1  3
    ## r2  2  4
    ## attr(,"rowtype")
    ## [1] "row"
    ## attr(,"coltype")
    ## [1] "col"

    elementapply_byname(divide, a = m, row = 1, col = 1, .FUNdots = list(divisor = 2))

    ##     c1 c2
    ## r1 0.5  3
    ## r2 2.0  4
    ## attr(,"rowtype")
    ## [1] "row"
    ## attr(,"coltype")
    ## [1] "col"

## `binaryapply_byname`

`binaryapply_byname` applies `FUN` to a pair of matrices, a pair of lists of matrices, or (if used with `dplyr::mutate`) a pair of columns in a data frame that contains matrices.

`match_type` must be one of `"all"`, `"matmult"`, or `"none"`.

`match_type` value | Behaviour
--- | ---
`"all"` | rowtypes of `a` must match rowtypes of `b` and coltypes of `a` must match coltypes of `b` (the default)
`"matmult"` | coltypes of `a` must match rowtypes of `b`
`"none"` | neither coltypes nor rowtypes are checked

The `rowcoltypes` argument (a boolean) tells whether to apply row and column types from `a` and `b` to the output.

The `.organize` argument (a boolean) tells whether to automatically complete `a` and `b` relative to each other and sort the rows and columns of the completed matrices. Normally, this should be `TRUE` (the default).

A simple example follows.

    U <- matrix(1:4, ncol = 2, dimnames = list(c("p1", "p2"), c("i1", "i2"))) %>%
      setrowtype("Products") %>% setcoltype("Industries")
    U

    ##    i1 i2
    ## p1  1  3
    ## p2  2  4
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

    Y <- matrix(1:4, ncol = 2, dimnames = list(c("p2", "p1"), c("i2", "i1"))) %>%
      setrowtype("Products") %>% setcoltype("Industries")
    Y

    ##    i2 i1
    ## p2  1  3
    ## p1  2  4
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

    sum_byname(U, Y)

    ##    i1 i2
    ## p1  5  5
    ## p2  5  5
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

    binaryapply_byname(`+`, U, Y)

    ##    i1 i2
    ## p1  5  5
    ## p2  5  5
    ## attr(,"rowtype")
    ## [1] "Products"
    ## attr(,"coltype")
    ## [1] "Industries"

## `cumapply_byname`

`cumapply_byname` applies `FUN` cumulatively to a list of numbers, a list of matrices, or (if used with `dplyr::mutate`) a column of a data frame. `FUN` must be a binary function that also allows a single argument. The result is a list with first element `FUN(m[[1]])`. For `i >= 2`, elements of the resulting list are `FUN(m[[i]], out[[i-1]])`, where `out` is the result list.

Simple examples follow.

    cumapply_byname(sum_byname, list(1, 2, 3, 4))

    ## [[1]]
    ## [1] 1
    ##
    ## [[2]]
    ## [1] 3
    ##
    ## [[3]]
    ## [1] 6
    ##
    ## [[4]]
    ## [1] 10

    cumapply_byname(hadamardproduct_byname, list(1, 2, 3, 4))

    ## [[1]]
    ## [1] 1
    ##
    ## [[2]]
    ## [1] 2
    ##
    ## [[3]]
    ## [1] 6
    ##
    ## [[4]]
    ## [1] 24

## Summary

The various `*apply_byname` functions allow users to extend the functionality of the `matsbyname` package as needed for any problem domain. The functions are used extensively in `matsbyname` itself. In fact, all `matsbyname` functions utilize the `*apply_byname` functions, so they are ready for prime time!