【问题标题】:printing matrices and vectors side by side并排打印矩阵和向量
【发布时间】:2017-01-18 01:54:40
【问题描述】:

出于教程目的,我希望能够并排打印或显示矩阵和向量,通常是为了说明矩阵方程的结果,例如 $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 数组显示为其切片的并排集合的紧凑方式。

这是否敲响了警钟,或者有人对开始有什么建议吗?

【问题讨论】:

标签: r matrix formatting


【解决方案1】:

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

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    

还可以并排打印 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

【讨论】:

  • 这让我走到了我想去的地方,但我不太明白如何增加矩阵之间的间距,除了添加" " 参数,也很好显示那些有名字的参数的名字。
  • 我已经扩展了答案以使列的宽度可配置并添加带有矩阵名称的标题。
  • 这方面做得很好,@Stibu!我用 x = as.matrix(c("x1", "x2", "x3"), ncol=1) 将 x 变成了一个字符矩阵,效果也很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多