并排打印矩阵和向量

时间:2016-09-09 20:59:55

标签: r matrix formatting

出于教学目的,我希望能够并排打印或显示矩阵和向量,通常用于说明矩阵方程的结果,如$ A x = b $。

我可以使用SAS / IML执行此操作,其中print语句采用任意(空格分隔)表达式的集合,计算它们并打印结果,例如

print A ' * ' x '=' (A * x) '=' b;

                    A                     X   #TEM1001       B
                    1     1    -4  *  0.733 =        2 =     2
                    1    -2     1     -0.33          1       1
                    1     1     1      -0.4          0       0

请注意,引用的字符串按原样打印。

我已经搜索过了,但在R中却找不到这样的东西。我想这样的事情可以通过函数showObj(object, ...)获取其参数列表,将每个参数格式化为一个字符块并加入它们来完成侧由端。

另一种用途是将3D数组显示为其切片的并排集合的紧凑方式。

这是响铃还是有人建议开始使用?

1 个答案:

答案 0 :(得分:2)

我创建了一个非常简单的函数,可以在其间打印具有任意字符串(通常是运算符)的矩阵和向量。它允许具有不同行数的矩阵,并将向量视为列矩阵。它不是很精细,所以我担心有许多例子它失败了。但是对于一个像你问题中那样简单的例子,它就足够了。

format()用于将数字转换为字符。这具有以下优点:矩阵的所有行具有相同的宽度,因此在打印时很好地对齐。如果需要,您可以将format()的一些参数也添加为参数mat_op_print()以使其可配置。作为示例,我添加了可用于控制列的最小宽度的参数width

如果矩阵和向量是函数调用中的名称,则这些名称将作为标题打印在第一行中。否则,只打印数字。

所以,这是函数:

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")
  }
}

这是一个如何运作的例子:

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                        x          y          b      
##   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    

也可以并排打印三维阵列的切片:

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