Printed matrices and vectors side by side

For training purposes, I would like to be able to print or display matrices and vectors side by side, often to illustrate the result of a matrix equation, for example $ A x = b $.

I could do this using SAS / IML, where the print statement takes an arbitrary collection of (spatially separated) expressions, evaluates them and prints the result, e.g.

 print A ' * ' x '=' (A * x) '=' b; AX #TEM1001 B 1 1 -4 * 0.733 = 2 = 2 1 -2 1 -0.33 1 1 1 1 1 -0.4 0 0 

Please note that quoted lines print as is.

I searched, but cannot find anything like it in R. I assume that something like this can be done using the showObj(object, ...) function, which showObj(object, ...) over its argument list, formats each of the character blocks and attaches them to the side side.

Another application of this would be a compact way to display a 3D array in side view of its fragments.

Does this ring a bell or does anyone have a suggestion for a start?

+5
source share
1 answer

I created a very simple function that can print matrices and vectors with arbitrary character strings (usually operators) between them. It allows you to use matrices with different numbers of rows and consider vectors as matrixes of columns. It is not very difficult, so I am afraid that there are many examples where it fails. But for an example similar to the simple one in your question, that should be enough.

format() used to convert numbers to characters. This has the advantage that all rows of the matrix have the same width and are thus well aligned when printing. If necessary, you can add some format() arguments also as mat_op_print() arguments to make it customizable. As an example, I added the argument width , which can be used to control the minimum width of columns.

If matrices and vectors are names in a function call, these names are printed as headers in the first line. Otherwise, only numbers are printed.

So this is the function:

 mat_op_print <- function(..., width = 0) { # get arguments args <- list(...) chars <- sapply(args, is.character) # auxilliary function to create character of n spaces spaces <- function(n) paste(rep(" ", n), collapse = "") # convert vectors to row matrix vecs <- sapply(args, is.vector) args[vecs & !chars] <- lapply(args[vecs & !chars], function(v) matrix(v, ncol = 1)) # convert all non-characters to character with format args[!chars] <- lapply(args[!chars], format, width = width) # print names as the first line, if present arg_names <- names(args) if (!is.null(arg_names)) { get_title <- function(x, name) { if (is.matrix(x)) { paste0(name, spaces(sum(nchar(x[1, ])) + ncol(x) - 1 - nchar(name))) } else { spaces(nchar(x)) } } cat(mapply(get_title, args, arg_names), "\n") } # auxiliary function to create the lines get_line <- function(x, n) { if (is.matrix(x)) { if (nrow(x) < n) { spaces(sum(nchar(x[1, ])) + ncol(x) - 1) } else { paste(x[n, ], collapse = " ") } } else if (n == 1) { x } else { spaces(nchar(x)) } } # print as many lines as needed for the matrix with most rows N <- max(sapply(args[!chars], nrow)) for (n in 1:N) { cat(sapply(args, get_line, n), "\n") } } 

And this is an example of how this works:

 A = matrix(c(0.5, 1, 3, 0.75, 2.8, 4), nrow = 2) x = c(0.5, 3.7, 2.3) y = c(0.7, -1.2) b = A %*% x - y mat_op_print(A = A, " * ", x = x, " - ", y = y, " = ", b = b, width = 6) ## A xyb ## 0.50 3.00 2.80 * 0.5 - 0.7 = 17.090 ## 1.00 0.75 4.00 3.7 -1.2 13.675 ## 2.3 

It is also possible to print slices of a three-dimensional array side by side:

 A <- array(1:12, dim = c(2, 2, 3)) mat_op_print(A1 = A[, , 1], " | ", A2 = A[, , 2], " | ", A3 = A[, , 3]) ## A1 A2 A3 ## 1 3 | 5 7 | 9 11 ## 2 4 6 8 10 12 
+2
source

All Articles