使用 xtable 打印 data.table 时控制输出
Controlling output while printing data.table with xtable
这是一个有很多记录/行的data.table
:
dt <- data.table(a=sample(letters,1000,replace = T), b=rnorm(1000))
我们可以简单地查看它:
dt
...并且生成了一个非常方便的视图,其中包含前 5 行和后 5 行。
但是,当使用 xtable
使用 knitr
打印 pdf 报告时,xtable
打印所有千行:
print(xtable(dt))
有什么解决办法吗?
我想要来自 xtable
的漂亮 table,但采用 data.table
的默认格式。
像 rbind
这样的具有前五个元素和后五个元素的 hack 是可能的,但不是很优雅。
这是 print.data.table
的修改版本,returns 格式化对象而不是打印它:
firstLast <- function(x, ...) {
UseMethod("firstLast")
}
firstLast.data.table <- function (x,
topn = getOption("datatable.print.topn"),
nrows = getOption("datatable.print.nrows"),
row.names = TRUE, ...) {
if (!is.numeric(nrows))
nrows = 100L
if (!is.infinite(nrows))
nrows = as.integer(nrows)
if (nrows <= 0L)
return(invisible())
if (!is.numeric(topn))
topn = 5L
topnmiss = missing(topn)
topn = max(as.integer(topn), 1L)
if (nrow(x) == 0L) {
if (length(x) == 0L)
return("Null data.table (0 rows and 0 cols)\n")
else return(paste("Empty data.table (0 rows) of ", length(x),
" col", if (length(x) > 1L)
"s", ": ", paste(head(names(x), 6), collapse = ","),
if (ncol(x) > 6)
"...", "\n", sep = ""))
}
if (topn * 2 < nrow(x) && (nrow(x) > nrows || !topnmiss)) {
toprint = rbind(head(x, topn), tail(x, topn))
rn = c(seq_len(topn), seq.int(to = nrow(x), length.out = topn))
printdots = TRUE
}
else {
toprint = x
rn = seq_len(nrow(x))
printdots = FALSE
}
toprint = data.table:::format.data.table(toprint, ...)
if (isTRUE(row.names))
rownames(toprint) = paste(format(rn, right = TRUE), ":",
sep = "")
else rownames(toprint) = rep.int("", nrow(x))
if (is.null(names(x)))
colnames(toprint) = rep("NA", ncol(toprint))
if (printdots) {
toprint = rbind(head(toprint, topn), `---` = "", tail(toprint,
topn))
rownames(toprint) = format(rownames(toprint), justify = "right")
return(toprint)
}
if (nrow(toprint) > 20L)
toprint = rbind(toprint, matrix(colnames(toprint), nrow = 1))
return(toprint)
}
这可以用来准备一个大的 data.table 用于 xtable 的格式化:
library(xtable)
xtable(firstLast(dt))
% latex table generated in R 3.1.2 by xtable 1.7-4 package
% Tue Feb 17 20:15:12 2015
\begin{table}[ht]
\centering
\begin{tabular}{rll}
\hline
& a & b \
\hline
1: & i & -0.6356429 \
2: & w & -1.1533783 \
3: & r & -0.7459959 \
4: & x & 1.5646809 \
5: & o & -1.8158744 \
--- & & \
996: & z & -1.0835897 \
997: & a & 0.9219506 \
998: & q & 0.3388118 \
999: & l & -1.7123250 \
1000: & l & 0.1240633 \
\hline
\end{tabular}
\end{table}
这是一个有很多记录/行的data.table
:
dt <- data.table(a=sample(letters,1000,replace = T), b=rnorm(1000))
我们可以简单地查看它:
dt
...并且生成了一个非常方便的视图,其中包含前 5 行和后 5 行。
但是,当使用 xtable
使用 knitr
打印 pdf 报告时,xtable
打印所有千行:
print(xtable(dt))
有什么解决办法吗?
我想要来自 xtable
的漂亮 table,但采用 data.table
的默认格式。
像 rbind
这样的具有前五个元素和后五个元素的 hack 是可能的,但不是很优雅。
这是 print.data.table
的修改版本,returns 格式化对象而不是打印它:
firstLast <- function(x, ...) {
UseMethod("firstLast")
}
firstLast.data.table <- function (x,
topn = getOption("datatable.print.topn"),
nrows = getOption("datatable.print.nrows"),
row.names = TRUE, ...) {
if (!is.numeric(nrows))
nrows = 100L
if (!is.infinite(nrows))
nrows = as.integer(nrows)
if (nrows <= 0L)
return(invisible())
if (!is.numeric(topn))
topn = 5L
topnmiss = missing(topn)
topn = max(as.integer(topn), 1L)
if (nrow(x) == 0L) {
if (length(x) == 0L)
return("Null data.table (0 rows and 0 cols)\n")
else return(paste("Empty data.table (0 rows) of ", length(x),
" col", if (length(x) > 1L)
"s", ": ", paste(head(names(x), 6), collapse = ","),
if (ncol(x) > 6)
"...", "\n", sep = ""))
}
if (topn * 2 < nrow(x) && (nrow(x) > nrows || !topnmiss)) {
toprint = rbind(head(x, topn), tail(x, topn))
rn = c(seq_len(topn), seq.int(to = nrow(x), length.out = topn))
printdots = TRUE
}
else {
toprint = x
rn = seq_len(nrow(x))
printdots = FALSE
}
toprint = data.table:::format.data.table(toprint, ...)
if (isTRUE(row.names))
rownames(toprint) = paste(format(rn, right = TRUE), ":",
sep = "")
else rownames(toprint) = rep.int("", nrow(x))
if (is.null(names(x)))
colnames(toprint) = rep("NA", ncol(toprint))
if (printdots) {
toprint = rbind(head(toprint, topn), `---` = "", tail(toprint,
topn))
rownames(toprint) = format(rownames(toprint), justify = "right")
return(toprint)
}
if (nrow(toprint) > 20L)
toprint = rbind(toprint, matrix(colnames(toprint), nrow = 1))
return(toprint)
}
这可以用来准备一个大的 data.table 用于 xtable 的格式化:
library(xtable)
xtable(firstLast(dt))
% latex table generated in R 3.1.2 by xtable 1.7-4 package
% Tue Feb 17 20:15:12 2015
\begin{table}[ht]
\centering
\begin{tabular}{rll}
\hline
& a & b \
\hline
1: & i & -0.6356429 \
2: & w & -1.1533783 \
3: & r & -0.7459959 \
4: & x & 1.5646809 \
5: & o & -1.8158744 \
--- & & \
996: & z & -1.0835897 \
997: & a & 0.9219506 \
998: & q & 0.3388118 \
999: & l & -1.7123250 \
1000: & l & 0.1240633 \
\hline
\end{tabular}
\end{table}