对于以下矩阵:
> 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
为每个行加上前缀?
答案 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)