如何使用 print 或 cat 缩进摘要等多行输出的输出,并保持列对齐?
How to indent output of multiline-outputs such as summary, using print or cat, and keep columns aligned?
这个问题可能概括为打印任何类型的多行输出,并保持列对齐。我的实际问题涉及 summary.default
.
的输出
我正在尝试将 2 的倍数的缩进添加到 summary.default
函数的 cat
输出中。我用cat
和print
做了一些尝试,也参考了一些相关的答案,但到目前为止都失败了。
f <- function(x) {
s <- summary.default(x)
liner <- Reduce(paste0, rep("-", 70))
cat("\n", liner, "\n") ## ATT 1. -------------------------------
cat("\n", "foo first attempt", "\n")
cat("\n--|\n")
print(round(s, 3)) #
cat("\n----|\n")
cat("\n *additional information\n")
cat("\n", liner, "\n") ## ATT 2. -------------------------------
cat("\n", "foo second attempt", "\n")
cat("\n--|\n")
print(unname(as.data.frame(cbind(" ", t(attr(s, "names"))))), row.names=F) #
print(unname(as.data.frame(cbind(" ", t(round(unclass(s), 3))))), row.names=F) #
cat("\n----|\n")
cat("\n *additional information\n")
cat("\n", liner, "\n") ## ATT 3. -------------------------------
cat("\n", "foo third attempt", "\n")
cat("\n--|\n")
cat("\n ", attr(s, "names"), "\n")
cat("\n ", round(s, 3), "\n") #
cat("\n----|\n")
cat("\n *additional information\n")
}
> x <- rnorm(100)
> f(x)
----------------------------------------------------------------------
foo first attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
----------------------------------------------------------------------
foo second attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
----------------------------------------------------------------------
foo third attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
---|
表示所需的缩进。 第一次尝试 没有任何缩进。 第二次尝试 更好,但行与行之间还有额外的 space,并且在四舍五入到不同数字时不能概括。在 尝试 3 时,列不再对齐。
如何使用 R 附带的功能获得所需的输出?
期望的输出:
----------------------------------------------------------------------
foo some text
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
*additional information
我唯一能想到的就是手动重新assemble 'summary' 输出以说明不同的 'cell' 宽度:
add_indent_and_right_align <- function(summry, indent=2, minDist= 2, rounding = 3) {
# add an indent and then right-align summary output table
#
# summry - summary object
# indent - integer Number of spaces to add before summary output
# minDist . integer Minimal number of spaces between two columns
# rounding - integer Number of decimals to round summary to
header <- attr(summry, "names")
value <- round(summry, 3)
r = list()
for (i in seq_along(header)) {
# find out how wide the column has to be
# to fit header and value and indent (if first column) or minDist
#
max_len <- max(nchar(header[i]), nchar(value[i]))
if (i == 1) {
cell_width <- max_len + indent
r[1] <- paste0(paste0(rep(" ", cell_width - nchar(header[i])), collapse=""), header[i])
r[2] <- paste0(paste0(rep(" ", cell_width - nchar(value[i])), collapse=""), value[i])
} else {
cell_width <- max_len + minDist
r[1] <- paste0(r[1], paste0(rep(" ", cell_width - nchar(header[i])), collapse=""), header[i])
r[2] <- paste0(r[2], paste0(rep(" ", cell_width - nchar(value[i])), collapse=""), value[i])
}
}
return(paste0(r, collapse="\n"))
}
f <- function(x) {
indent <- 4 # how many spaces shoud the whole summary output be indented?
s <- summary.default(x)
cat(paste0(rep("-", 70), collapse=""), "\n")
cat("\n")
cat("foo some text", "\n")
cat("\n")
cat(add_indent_and_right_align(summry=s, indent=4, minDist= 1, rounding = 3), "\n")
cat("\n")
cat(paste0(paste0(rep(" ", indent), collapse=""), "*additional information"), "\n")
cat("\n")
}
set.seed(1)
x <- rnorm(100)
f(x)
Returns:
----------------------------------------------------------------------
foo some text
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.215 -0.494 0.114 0.109 0.692 2.402
*additional information
对于此任务,您可以连续使用 base r 的两个函数。有一个函数 capture.output
可以捕获像 print 这样的命令的输出。使用 paste
组合所需数量的空格,可以将其写入标准输出 writelines
,从而保留数据帧打印输出的行结构。
要执行上述操作,请将打印输出中给出的所有信息作为示例合并到 data.frame (df).
df = data.frame("Min."=-2.069, "First Qu."= -0.654, "Median"= -0.092 , "Mean" =-0.075, "Third Qu."= 0.696, "Max."= 1.997 )
writeLines(paste0(" ", capture.output(print(df, row.names = F))))
我添加了 roe.names = F,以禁止打印数据帧的行号
这个问题可能概括为打印任何类型的多行输出,并保持列对齐。我的实际问题涉及 summary.default
.
我正在尝试将 2 的倍数的缩进添加到 summary.default
函数的 cat
输出中。我用cat
和print
做了一些尝试,也参考了一些相关的答案,但到目前为止都失败了。
f <- function(x) {
s <- summary.default(x)
liner <- Reduce(paste0, rep("-", 70))
cat("\n", liner, "\n") ## ATT 1. -------------------------------
cat("\n", "foo first attempt", "\n")
cat("\n--|\n")
print(round(s, 3)) #
cat("\n----|\n")
cat("\n *additional information\n")
cat("\n", liner, "\n") ## ATT 2. -------------------------------
cat("\n", "foo second attempt", "\n")
cat("\n--|\n")
print(unname(as.data.frame(cbind(" ", t(attr(s, "names"))))), row.names=F) #
print(unname(as.data.frame(cbind(" ", t(round(unclass(s), 3))))), row.names=F) #
cat("\n----|\n")
cat("\n *additional information\n")
cat("\n", liner, "\n") ## ATT 3. -------------------------------
cat("\n", "foo third attempt", "\n")
cat("\n--|\n")
cat("\n ", attr(s, "names"), "\n")
cat("\n ", round(s, 3), "\n") #
cat("\n----|\n")
cat("\n *additional information\n")
}
> x <- rnorm(100)
> f(x)
----------------------------------------------------------------------
foo first attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
----------------------------------------------------------------------
foo second attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
----------------------------------------------------------------------
foo third attempt
--|
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
----|
*additional information
---|
表示所需的缩进。 第一次尝试 没有任何缩进。 第二次尝试 更好,但行与行之间还有额外的 space,并且在四舍五入到不同数字时不能概括。在 尝试 3 时,列不再对齐。
如何使用 R 附带的功能获得所需的输出?
期望的输出:
----------------------------------------------------------------------
foo some text
Min. 1st Qu. Median Mean 3rd Qu. Max.
-2.069 -0.654 -0.092 -0.075 0.696 1.997
*additional information
我唯一能想到的就是手动重新assemble 'summary' 输出以说明不同的 'cell' 宽度:
add_indent_and_right_align <- function(summry, indent=2, minDist= 2, rounding = 3) {
# add an indent and then right-align summary output table
#
# summry - summary object
# indent - integer Number of spaces to add before summary output
# minDist . integer Minimal number of spaces between two columns
# rounding - integer Number of decimals to round summary to
header <- attr(summry, "names")
value <- round(summry, 3)
r = list()
for (i in seq_along(header)) {
# find out how wide the column has to be
# to fit header and value and indent (if first column) or minDist
#
max_len <- max(nchar(header[i]), nchar(value[i]))
if (i == 1) {
cell_width <- max_len + indent
r[1] <- paste0(paste0(rep(" ", cell_width - nchar(header[i])), collapse=""), header[i])
r[2] <- paste0(paste0(rep(" ", cell_width - nchar(value[i])), collapse=""), value[i])
} else {
cell_width <- max_len + minDist
r[1] <- paste0(r[1], paste0(rep(" ", cell_width - nchar(header[i])), collapse=""), header[i])
r[2] <- paste0(r[2], paste0(rep(" ", cell_width - nchar(value[i])), collapse=""), value[i])
}
}
return(paste0(r, collapse="\n"))
}
f <- function(x) {
indent <- 4 # how many spaces shoud the whole summary output be indented?
s <- summary.default(x)
cat(paste0(rep("-", 70), collapse=""), "\n")
cat("\n")
cat("foo some text", "\n")
cat("\n")
cat(add_indent_and_right_align(summry=s, indent=4, minDist= 1, rounding = 3), "\n")
cat("\n")
cat(paste0(paste0(rep(" ", indent), collapse=""), "*additional information"), "\n")
cat("\n")
}
set.seed(1)
x <- rnorm(100)
f(x)
Returns:
---------------------------------------------------------------------- foo some text Min. 1st Qu. Median Mean 3rd Qu. Max. -2.215 -0.494 0.114 0.109 0.692 2.402 *additional information
对于此任务,您可以连续使用 base r 的两个函数。有一个函数 capture.output
可以捕获像 print 这样的命令的输出。使用 paste
组合所需数量的空格,可以将其写入标准输出 writelines
,从而保留数据帧打印输出的行结构。
要执行上述操作,请将打印输出中给出的所有信息作为示例合并到 data.frame (df).
df = data.frame("Min."=-2.069, "First Qu."= -0.654, "Median"= -0.092 , "Mean" =-0.075, "Third Qu."= 0.696, "Max."= 1.997 )
writeLines(paste0(" ", capture.output(print(df, row.names = F))))
我添加了 roe.names = F,以禁止打印数据帧的行号