Skip to content

Commit e6cca92

Browse files
committed
A pair of functions for mapping beteen array and element list and a helper function for setting diagonal in a pipe.
1 parent bf500c0 commit e6cca92

5 files changed

Lines changed: 166 additions & 1 deletion

File tree

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: statnet.common
2-
Version: 4.12.0-491
2+
Version: 4.12.0-496
33
Date: 2025-05-29
44
Title: Common R Scripts and Utilities Used by the Statnet Project Software
55
Authors@R: c(

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export(Welford)
6969
export(all_identical)
7070
export(append.rhs.formula)
7171
export(append_rhs.formula)
72+
export(arr_from_coo)
73+
export(arr_to_coo)
7274
export(as.control.list)
7375
export(as.linwmatrix)
7476
export(as.logwmatrix)
@@ -131,6 +133,7 @@ export(sandwich_sginv)
131133
export(sandwich_solve)
132134
export(sandwich_ssolve)
133135
export(set.control.class)
136+
export(set_diag)
134137
export(sginv)
135138
export(simplify_simple)
136139
export(snctrl)

R/matrix.utils.R

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,82 @@ sandwich_ginv <- function(A, B, ...) {
367367
Ai <- MASS::ginv(A, ...)
368368
Ai %*% B %*% t(Ai)
369369
}
370+
371+
#' Conveniently covert between coordinate-value and array representations
372+
#'
373+
#' These function similarly to \CRANpkg{Matrix}'s utilities but is
374+
#' simpler and allows arbitrary baseline and handling of missing
375+
#' values. (It is also almost certainly much slower.) Also, since it
376+
#' is likely that operations will be performed on the elements of the
377+
#' array, their argument is first for easier piping.
378+
#'
379+
#' If `x0` is `NA`, non-`NA` elements are returned; if `x0` is `NULL`,
380+
#' all elements are.
381+
#'
382+
#' @param x values of elements differing from the default.
383+
#' @param coord an integer matrix of their indices.
384+
#' @param dim dimension vector; recycled to `ncol(coord)`; if not
385+
#' given, inferred from `dimnames`.
386+
#' @param x0 the default value.
387+
#' @param dimnames dimension name list.
388+
#' @param X an array.
389+
#' @param na.rm whether the `NA` elements of the array should be
390+
#' omitted from the list.
391+
#'
392+
#' @return `coo_to_arr()` returns a matrix or an array.
393+
#'
394+
#' @examples
395+
#' m <- matrix(rpois(25, 1), 5, 5)
396+
#' arr_to_coo(m, 0L)
397+
#' stopifnot(identical(do.call(arr_from_coo, arr_to_coo(m, 0L)), m))
398+
#'
399+
#' stopifnot(length(arr_to_coo(m, NULL)$x) == 25) # No baseline
400+
#'
401+
#' m[sample.int(25L, 2L)] <- NA
402+
#' m
403+
#' arr_to_coo(m, 0L) # Return NAs
404+
#'
405+
#' arr_to_coo(m, 0L, na.rm = TRUE) # Drop NAs
406+
#' @export
407+
arr_from_coo <- function(x, coord, dim = lengths(dimnames), x0 = NA, dimnames = NULL) {
408+
coord <- as.matrix(coord)
409+
dim <- rep_len(dim, ncol(coord))
410+
if (anyNA(dim)) stop("array dimensions not specified")
411+
replace(array(NVL(x0, NA), dim, dimnames), coord, x)
412+
}
413+
414+
#' @rdname arr_from_coo
415+
#' @return `arr_to_coo()` returns a list with the following elements:
416+
#'
417+
#' \item{`x`}{the values distinct from `x0`}
418+
#'
419+
#' \item{`coord`}{a matrix with a column for each dimension containing
420+
#' indexes of values distinct from `x0`}
421+
#'
422+
#' \item{`dim`}{the dimension vector of the matrix}
423+
#'
424+
#' \item{`dimnames`}{the dimension name list of the matrix}
425+
#'
426+
#' @export
427+
arr_to_coo <- function(X, x0, na.rm = FALSE) {
428+
nz <- if (is.null(x0)) seq_along(X)
429+
else if (is.na(x0)) which(!is.na(X))
430+
else if (na.rm) which(X != x0)
431+
else which(is.na(X) | X != x0)
432+
coord <- arrayInd(nz, d <- dim(X), dn <- dimnames(X), TRUE)
433+
list(x = X[nz], coord = coord, dim = d, x0 = x0, dimnames = dn)
434+
}
435+
436+
#' Return the matrix with diagonal set to a specified value
437+
#'
438+
#' This function simply assigns `value` to diagonal of `x` and returns
439+
#' `x`.
440+
#'
441+
#' @param x a square matrix.
442+
#' @param value a value or a vector (recycled to the required length).
443+
#'
444+
#' @export
445+
set_diag <- function(x, value) {
446+
diag(x) <- value
447+
x
448+
}

man/arr_from_coo.Rd

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/set_diag.Rd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)