如何从 sprintf 打印 R 矩阵
How to print R matrix from sprintf
对于以下矩阵:
> 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 来实现?
UPDATE 来自 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] ""
第三次更新 我添加了一个灵活的 "message/matrix name" 参数。但是 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
在每个行前加上消息?
这是 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)
使用 sprintf()
,您会将整个矩阵转换为字符,这使得以后访问它们的数值变得更加困难。
相反,您可以使用 listof
class 然后您仍然可以访问所有数值。首先将矩阵(或多个矩阵)放入命名列表中。快速浏览一下它的外观。
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
class 添加到包含 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")
对于以下矩阵:
> 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 来实现?
UPDATE 来自 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] ""
第三次更新 我添加了一个灵活的 "message/matrix name" 参数。但是 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
在每个行前加上消息?
这是 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)
使用 sprintf()
,您会将整个矩阵转换为字符,这使得以后访问它们的数值变得更加困难。
相反,您可以使用 listof
class 然后您仍然可以访问所有数值。首先将矩阵(或多个矩阵)放入命名列表中。快速浏览一下它的外观。
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
class 添加到包含 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")