@@ -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+ }
0 commit comments