如何从sprintf打印R矩阵

时间:2015-01-18 20:10:52

标签: r printf

对于以下矩阵:

> mat
             [,1]          [,2]          [,3]
[1,] 8.326673e-17  5.551115e-17  5.551115e-17
[2,] 2.775558e-17  3.677614e-16 -5.551115e-17
[3,] 0.000000e+00 -2.775558e-17  5.551115e-17

考虑以下sprintf

sprintf("proj: %s", mat)

输出结果为:

print(sprintf("proj: %s", mat))
[1] "proj: 8.32667268468867e-17"  "proj: 2.77555756156289e-17"
[3] "proj: 0"                     "proj: 5.55111512312578e-17"
[5] "proj: 3.67761376907083e-16"  "proj: -2.77555756156289e-17"
[7] "proj: 5.55111512312578e-17"  "proj: -5.55111512312578e-17"
[9] "proj: 5.55111512312578e-17"

我们想要的是与mat相同的输出,但使用

  

" proj:"

消息前置。具体做法是:

proj:             [,1]          [,2]          [,3]
[1,] 8.326673e-17  5.551115e-17  5.551115e-17
[2,] 2.775558e-17  3.677614e-16 -5.551115e-17
[3,] 0.000000e+00 -2.775558e-17  5.551115e-17

如何使用sprintf实现这一目标?

更新从Sven的回答中,尝试创建一个函数就在这里:

printmat <- function(mat) {
  out <- capture.output(mat)
  out[1] <- paste0("proj:", out[1])
  paste(out, collapse = "\n")
}

这是输出:单行(比原版更好4行):

print(printmat(mat))

[1] "proj:             [,1]          [,2]          [,3]\n[1,] 8.326673e-17  5.551115e-17  5.551115e-17\n[2,] 2.775558e-17  3.677614e-16 -5.551115e-17\n[3,] 0.000000e+00 -2.775558e-17  5.551115e-17"

另一次更新来自Richard Scriven的另一个答案 - 使用print.listof(list)。这是一个包含capture.output的函数。然而,该解决方案不允许灵活消息:它被硬编码为"proj"

printmat <- function(mat) {
  out <- capture.output(print.listof(list(proj = mat)))
}

以下是输出: close ..但请注意,我们无法选择将"proj"更改为其他内容:

   print(printmat(mat))

[1] "proj :"
[2] "             [,1]          [,2]          [,3]"
[3] "[1,] 8.326673e-17  5.551115e-17  5.551115e-17"
[4] "[2,] 2.775558e-17  3.677614e-16 -5.551115e-17"
[5] "[3,] 0.000000e+00 -2.775558e-17  5.551115e-17"
[6] ""

第三次更新我添加了一个灵活的&#34;消息/矩阵名称&#34;参数。但是sprintf会将它添加到输出的每一行:

printmat <- function(msg, mat) {
  out <- capture.output(print.listof(list(mat)))
  sprintf("%s: %s", msg, out)
}

这是一个测试:

> print(printmat("mymat", mat))
[1] "mymat: Component 1 :"
[2] "mymat:              [,1]          [,2]          [,3]"
[3] "mymat: [1,] 8.326673e-17  5.551115e-17  5.551115e-17"
[4] "mymat: [2,] 2.775558e-17  3.677614e-16 -5.551115e-17"
[5] "mymat: [3,] 0.000000e+00 -2.775558e-17  5.551115e-17"
[6] "mymat:

那么有没有办法阻止 sprintf 每个行加上前缀?

2 个答案:

答案 0 :(得分:3)

使用sprintf(),您会将整个矩阵转换为字符,从而使以后更难以访问其数字值。

相反,您可以使用listof类,然后您仍然可以访问所有数值。首先将矩阵(或矩阵)放入命名列表中。这里快速浏览一下它的样子。

m <- structure(c(8.326673e-17, 2.775558e-17, 0, 5.551115e-17, 3.677614e-16, 
-2.775558e-17, 5.551115e-17, -5.551115e-17, 5.551115e-17), .Dim = c(3L, 
3L))

print.listof(list(proj = m))
# proj :
#              [,1]          [,2]          [,3]
# [1,] 8.326673e-17  5.551115e-17  5.551115e-17
# [2,] 2.775558e-17  3.677614e-16 -5.551115e-17
# [3,] 0.000000e+00 -2.775558e-17  5.551115e-17

为了实现这一点,我们不需要致电print.listof(),我们可以将listof类添加到包含m的列表中。然后它将按您想要的方式打印,您仍然可以不变地访问矩阵值。

mm <- list(proj = m)
class(mm) <- "listof"
mm
# proj :
#              [,1]          [,2]          [,3]
# [1,] 8.326673e-17  5.551115e-17  5.551115e-17
# [2,] 2.775558e-17  3.677614e-16 -5.551115e-17
# [3,] 0.000000e+00 -2.775558e-17  5.551115e-17    
mm$proj[1,]
# [1] 8.326673e-17 5.551115e-17 5.551115e-17

您只需更改mm

的名称,即可随时更改第一行
setNames(mm, "PROJ")
# PROJ :
#              [,1]          [,2]          [,3]
# [1,] 8.326673e-17  5.551115e-17  5.551115e-17
# [2,] 2.775558e-17  3.677614e-16 -5.551115e-17
# [3,] 0.000000e+00 -2.775558e-17  5.551115e-17

最后,我们将如何将所有这些信息用作函数:

f <- function(mat, nm) {
    x <- setNames(list(mat), nm)
    class(x) <- "listof"
    x
}

f(m, "proj")
f(m, "project 1")

答案 1 :(得分:2)

这是capture.output的方法:

# an example matrix
mat <- matrix(rnorm(9), nrow = 3)

# standard print output
out <- capture.output(mat)
# modify first line
out[1] <- paste0("proj:", out[1])
# print modified version
cat(paste(out, collapse = "\n"))

输出:

proj:          [,1]       [,2]      [,3]
[1,] 0.8760935 -0.8395728 -1.569009
[2,] 0.2660100 -2.2364285 -1.872737
[3,] 0.4996019 -0.6997563 -2.136702

作为一项功能:

printmat <- function(mat) {
  out <- capture.output(mat)
  out[1] <- paste0("proj:", out[1])
  cat(paste(out, collapse = "\n"))
}


printmat(mat)