From e7e92b1b867e56cb961bdc7f9fafcfebf20e12ae Mon Sep 17 00:00:00 2001 From: venom1204 Date: Mon, 15 Jun 2026 21:24:28 +0000 Subject: [PATCH 01/13] added changes --- R/onLoad.R | 1 + R/print.data.table.R | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/R/onLoad.R b/R/onLoad.R index 46a9826fe4..ec71252b75 100644 --- a/R/onLoad.R +++ b/R/onLoad.R @@ -90,6 +90,7 @@ datatable.print.keys=TRUE, # for print.data.table datatable.print.trunc.cols=FALSE, # for print.data.table datatable.show.indices=FALSE, # for print.data.table + datatable.show.ncols=FALSE, # for print.data.table datatable.allow.cartesian=FALSE, # datatable. datatable.join.many=TRUE, # mergelist, [.data.table #4383 #914 datatable.dfdispatchwarn=TRUE, # not a function argument diff --git a/R/print.data.table.R b/R/print.data.table.R index 88ff4ea505..5a025638d3 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -8,6 +8,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), print.keys=getOption("datatable.print.keys"), trunc.cols=getOption("datatable.print.trunc.cols"), show.indices=getOption("datatable.show.indices"), + show.ncols=getOption("datatable.show.ncols", FALSE), quote=FALSE, na.print=NULL, timezone=FALSE, ...) { @@ -52,6 +53,9 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), paste0("<", ixs, ">", collapse = ", ") )) } + if (show.ncols && !isTRUE(trunc.cols) && !any(dim(x)==0L)) { + catf("Number of columns: %d\n", ncol(x)) + } if (any(dim(x)==0L)) { x_class = if (is.data.table(x)) "data.table" else "data.frame" # a data.frame could be passed to print.data.table() directly, #3363 if (all(dim(x)==0L)) { @@ -116,6 +120,20 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), cons_width = getOption("width") cols_to_print = widths < cons_width not_printed = colnames(toprint)[!cols_to_print] + + if (show.ncols) { + n_not_printed = length(not_printed) + if (n_not_printed > 0L) { + if (class && col.names != "none") classes = paste0(" ", tail(abbs, n_not_printed)) else classes = "" + catf("Number of columns: %d, of which %d %s not shown: %s\n", + ncol(x), n_not_printed, ngettext(n_not_printed, "is", "are"), + brackify(paste0(not_printed, classes))) + trunc.cols = FALSE # message already printed in header + } else { + catf("Number of columns: %d\n", ncol(x)) + } + } + if (!any(cols_to_print)) { trunc_cols_message(not_printed, abbs, class, col.names) return(invisible(x)) @@ -123,7 +141,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), # When nrow(toprint) = 1, attributes get lost in the subset, # function below adds those back when necessary toprint = toprint_subset(toprint, cols_to_print) - trunc.cols = length(not_printed) > 0L + if (!show.ncols) trunc.cols = length(not_printed) > 0L else trunc.cols = FALSE } print_default = function(x) { if (col.names != "none") cut_colnames = identity From 021d6e21e560180cb7418bedf1dcf83d711e1935 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 15:08:01 +0000 Subject: [PATCH 02/13] .. --- R/print.data.table.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index 5a025638d3..ace6debe2e 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -135,13 +135,13 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), } if (!any(cols_to_print)) { - trunc_cols_message(not_printed, abbs, class, col.names) + if (!show.ncols) trunc_cols_message(not_printed, abbs, class, col.names) return(invisible(x)) } # When nrow(toprint) = 1, attributes get lost in the subset, # function below adds those back when necessary toprint = toprint_subset(toprint, cols_to_print) - if (!show.ncols) trunc.cols = length(not_printed) > 0L else trunc.cols = FALSE + trunc.cols = !show.ncols && length(not_printed) > 0L } print_default = function(x) { if (col.names != "none") cut_colnames = identity From 864954e9fce71e18eb5883586675e791ede44400 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 15:28:43 +0000 Subject: [PATCH 03/13] added test --- inst/tests/tests.Rraw | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 687bf929ed..c030cac706 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21660,3 +21660,10 @@ test(2374.08, key(DT[, .(a, a)]), NULL) test(2374.09, key(subset(DT, select=c(a, a))), NULL) DT = data.table(a=1:2, a.1=3:4, val=10:11) test(2374.10, key(DT[, .(a.1, sum(val)), keyby=.(a, a)]), NULL) + +#6663 Option to print the number of columns +test(2375.1, {options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT))[1L]}, "Number of columns: 5") +test(2375.2, {options(datatable.show.ncols=TRUE); DT=as.data.table(iris); setkey(DT, Sepal.Length); any(grepl("^Number of columns: 5$", capture.output(print(DT))))}, TRUE) +test(2375.3, {options(width=20); options(datatable.show.ncols=TRUE); DT=data.table(a=1:3,b=1:3,c=1:3,d=1:3,e=1:3); any(grepl("^5 variables not shown", capture.output(print(DT, trunc.cols=TRUE))))}, FALSE) +test(2375.4, {options(width=10); options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT, trunc.cols=TRUE))[1L]}, "Number of columns: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]") +test(2375.5, {options(datatable.show.ncols=FALSE); DT=as.data.table(iris); any(grepl("^Number of columns:", capture.output(print(DT))))}, FALSE) From 1850b3920d8fba0bebb5b1752830f5c26ed48f27 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 15:34:19 +0000 Subject: [PATCH 04/13] added doc --- R/print.data.table.R | 2 +- man/data.table-options.Rd | 1 + man/print.data.table.Rd | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index ace6debe2e..1dc0e6aed5 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -128,7 +128,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), catf("Number of columns: %d, of which %d %s not shown: %s\n", ncol(x), n_not_printed, ngettext(n_not_printed, "is", "are"), brackify(paste0(not_printed, classes))) - trunc.cols = FALSE # message already printed in header + trunc.cols = FALSE } else { catf("Number of columns: %d\n", ncol(x)) } diff --git a/man/data.table-options.Rd b/man/data.table-options.Rd index 439e88ef2f..90ed4e5f04 100644 --- a/man/data.table-options.Rd +++ b/man/data.table-options.Rd @@ -33,6 +33,7 @@ \item{\code{datatable.print.keys}}{A logical, default \code{FALSE}. If \code{TRUE}, the table's keys are printed above the data.} \item{\code{datatable.show.indices}}{A logical, default \code{TRUE}. A synonym for \code{datatable.print.keys} for historical reasons.} + \item{\code{datatable.show.ncols}}{A logical, default \code{FALSE}. If \code{TRUE}, the number of columns is printed in the header.} \item{\code{datatable.print.trunc.cols}}{A logical, default \code{FALSE}. If \code{TRUE} and a table has more columns than fit on the screen, it truncates the middle columns.} \item{\code{datatable.prettyprint.char}}{An integer, default \code{100L}. The maximum number of diff --git a/man/print.data.table.Rd b/man/print.data.table.Rd index 7d51a55fc1..4c21a25db0 100644 --- a/man/print.data.table.Rd +++ b/man/print.data.table.Rd @@ -25,6 +25,7 @@ print.keys=getOption("datatable.print.keys"), # default: TRUE trunc.cols=getOption("datatable.print.trunc.cols"), # default: FALSE show.indices=getOption("datatable.show.indices"), # default: FALSE + show.ncols=getOption("datatable.show.ncols"), # default: FALSE quote=FALSE, na.print=NULL, timezone=FALSE, \dots) @@ -43,6 +44,7 @@ \item{nrows}{ The number of rows which will be printed before truncation is enforced. } \item{class}{ If \code{TRUE}, the resulting output will include above each column its storage class (or a self-evident abbreviation thereof). When combined with \code{col.names="auto"} and tables >20 rows, classes will also appear at the bottom.} \item{row.names}{ If \code{TRUE}, row indices will be printed alongside \code{x}. } + \item{show.ncols}{ If \code{TRUE}, the number of columns is printed in the header. } \item{col.names}{ One of three flavours for controlling the display of column names in output. \code{"auto"} includes column names above the data, as well as below the table if \code{nrow(x) > 20} (when \code{class=TRUE}, column classes will also appear at the bottom). \code{"top"} excludes this lower register when applicable, and \code{"none"} suppresses column names altogether (as well as column classes if \code{class = TRUE}. } \item{print.keys}{ If \code{TRUE}, any \code{\link{key}} and/or \code{\link[=indices]{index}} currently assigned to \code{x} will be printed prior to the preview of the data. } \item{trunc.cols}{ If \code{TRUE}, only the columns that can be printed in the console without wrapping the columns to new lines will be printed (similar to \code{tibbles}). } From 78621ebd84482cb1a8ea9ae51629d19e502eb184 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 15:49:03 +0000 Subject: [PATCH 05/13] .. --- man/print.data.table.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/print.data.table.Rd b/man/print.data.table.Rd index 4c21a25db0..28334ab64f 100644 --- a/man/print.data.table.Rd +++ b/man/print.data.table.Rd @@ -25,7 +25,7 @@ print.keys=getOption("datatable.print.keys"), # default: TRUE trunc.cols=getOption("datatable.print.trunc.cols"), # default: FALSE show.indices=getOption("datatable.show.indices"), # default: FALSE - show.ncols=getOption("datatable.show.ncols"), # default: FALSE + show.ncols=getOption("datatable.show.ncols", FALSE), # default: FALSE quote=FALSE, na.print=NULL, timezone=FALSE, \dots) From 2aec2a5f42dd7488460e12909b1e9bf5f8c12a5d Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 16:00:43 +0000 Subject: [PATCH 06/13] .. --- inst/tests/tests.Rraw | 1 + 1 file changed, 1 insertion(+) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index c030cac706..a31f44c0dc 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21667,3 +21667,4 @@ test(2375.2, {options(datatable.show.ncols=TRUE); DT=as.data.table(iris); setkey test(2375.3, {options(width=20); options(datatable.show.ncols=TRUE); DT=data.table(a=1:3,b=1:3,c=1:3,d=1:3,e=1:3); any(grepl("^5 variables not shown", capture.output(print(DT, trunc.cols=TRUE))))}, FALSE) test(2375.4, {options(width=10); options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT, trunc.cols=TRUE))[1L]}, "Number of columns: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]") test(2375.5, {options(datatable.show.ncols=FALSE); DT=as.data.table(iris); any(grepl("^Number of columns:", capture.output(print(DT))))}, FALSE) +test(2375.6, {options(width=10); options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT, trunc.cols=TRUE, class=TRUE))[1L]}, "Number of columns: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]") From 3e58a320d2a9ee98489ab3e8b65a92f7ad85830a Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 18:55:55 +0000 Subject: [PATCH 07/13] removed empty lines --- R/print.data.table.R | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index 1dc0e6aed5..beac4cfac9 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -120,7 +120,6 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), cons_width = getOption("width") cols_to_print = widths < cons_width not_printed = colnames(toprint)[!cols_to_print] - if (show.ncols) { n_not_printed = length(not_printed) if (n_not_printed > 0L) { @@ -133,7 +132,6 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), catf("Number of columns: %d\n", ncol(x)) } } - if (!any(cols_to_print)) { if (!show.ncols) trunc_cols_message(not_printed, abbs, class, col.names) return(invisible(x)) From 43dddf29d6ac03973be9d5d5e2bf59a1491aac09 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Tue, 16 Jun 2026 19:00:10 +0000 Subject: [PATCH 08/13] added news --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 45a36dcf0c..10d3bc41c3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -32,6 +32,8 @@ 6. `yearqtr()` and `yearmon()` now gain an optional format specifier [#7694](https://github.com/Rdatatable/data.table/issues/7694). 'numeric' is the default, which preserves the original behavior, but 'character' formats `yearqtr()` as YYYYQ# (e.g. 2025Q2) and `yearmon()` as YYYYM## (e.g. 2025M02, 2025M10). Thanks to @jan-swissre for the report and @LunaticSage218 for the implementation. +7. `print.data.table()` gains a `show.ncols` argument and `datatable.show.ncols` option to print the number of columns (labeled as `ncol:`) in the header, [#6663](https://github.com/Rdatatable/data.table/issues/6663). When `trunc.cols=TRUE`, this information is merged into the truncation message at the top, and the redundant footer message is suppressed. Thanks to @KyleHaynes for the suggestion and @venom1204 for the implementation. + ### BUG FIXES 1. `fread()` with `skip=0` and `(header=TRUE|FALSE)` no longer skips the first row when it has fewer fields than subsequent rows, [#7463](https://github.com/Rdatatable/data.table/issues/7463). Thanks @emayerhofer for the report and @ben-schwen for the fix. From aa54da60c4747a5b745481261e43d169592317ce Mon Sep 17 00:00:00 2001 From: venom1204 Date: Thu, 25 Jun 2026 10:05:50 +0000 Subject: [PATCH 09/13] updated tests --- inst/tests/tests.Rraw | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 01d9151ea0..3d47f816ab 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21684,10 +21684,10 @@ x = as.data.table(as.list(1:max_ppsize)) test(2376, rbindlist(list(x)), x) rm(x, max_ppsize) -#6663 Option to print the number of columns -test(2375.1, {options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT))[1L]}, "Number of columns: 5") -test(2375.2, {options(datatable.show.ncols=TRUE); DT=as.data.table(iris); setkey(DT, Sepal.Length); any(grepl("^Number of columns: 5$", capture.output(print(DT))))}, TRUE) -test(2375.3, {options(width=20); options(datatable.show.ncols=TRUE); DT=data.table(a=1:3,b=1:3,c=1:3,d=1:3,e=1:3); any(grepl("^5 variables not shown", capture.output(print(DT, trunc.cols=TRUE))))}, FALSE) -test(2375.4, {options(width=10); options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT, trunc.cols=TRUE))[1L]}, "Number of columns: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]") -test(2375.5, {options(datatable.show.ncols=FALSE); DT=as.data.table(iris); any(grepl("^Number of columns:", capture.output(print(DT))))}, FALSE) -test(2375.6, {options(width=10); options(datatable.show.ncols=TRUE); DT=as.data.table(iris); capture.output(print(DT, trunc.cols=TRUE, class=TRUE))[1L]}, "Number of columns: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]") +#6663 Option to print the number of columns (ncol) +test(2377.1, capture.output(print(as.data.table(iris)))[1L], "ncol: 5", options=list(datatable.show.ncols=TRUE)) +test(2377.2, any(grepl("^ncol: 5$", capture.output(print(setkey(as.data.table(iris), Sepal.Length))))), TRUE, options=list(datatable.show.ncols=TRUE)) +test(2377.3, any(grepl("^[0-9]+ variables? not shown", capture.output(print(data.table(a=1:3, b=1:3, c=1:3, d=1:3, e=1:3), trunc.cols=TRUE)))), FALSE, options=list(width=20, datatable.show.ncols=TRUE)) +test(2377.4, capture.output(print(as.data.table(iris), trunc.cols=TRUE))[1L], "ncol: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]", options=list(width=10, datatable.show.ncols=TRUE)) +test(2377.5, any(grepl("^ncol:", capture.output(print(as.data.table(iris))))), FALSE, options=list(datatable.show.ncols=FALSE)) +test(2377.6, capture.output(print(as.data.table(iris), trunc.cols=TRUE, class=TRUE))[1L], "ncol: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]", options=list(width=10, datatable.show.ncols=TRUE)) From d4d80f1a1b1fadec39ee69f0f677331588c94559 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Thu, 25 Jun 2026 10:12:57 +0000 Subject: [PATCH 10/13] . --- inst/tests/tests.Rraw | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 3d47f816ab..474ca96e9a 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21684,10 +21684,10 @@ x = as.data.table(as.list(1:max_ppsize)) test(2376, rbindlist(list(x)), x) rm(x, max_ppsize) -#6663 Option to print the number of columns (ncol) -test(2377.1, capture.output(print(as.data.table(iris)))[1L], "ncol: 5", options=list(datatable.show.ncols=TRUE)) -test(2377.2, any(grepl("^ncol: 5$", capture.output(print(setkey(as.data.table(iris), Sepal.Length))))), TRUE, options=list(datatable.show.ncols=TRUE)) +#6663 Option to print the number of columns +test(2377.1, capture.output(print(as.data.table(iris)))[1L], "Number of columns: 5", options=list(datatable.show.ncols=TRUE)) +test(2377.2, any(grepl("^Number of columns: 5$", capture.output(print(setkey(as.data.table(iris), Sepal.Length))))), TRUE, options=list(datatable.show.ncols=TRUE)) test(2377.3, any(grepl("^[0-9]+ variables? not shown", capture.output(print(data.table(a=1:3, b=1:3, c=1:3, d=1:3, e=1:3), trunc.cols=TRUE)))), FALSE, options=list(width=20, datatable.show.ncols=TRUE)) -test(2377.4, capture.output(print(as.data.table(iris), trunc.cols=TRUE))[1L], "ncol: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]", options=list(width=10, datatable.show.ncols=TRUE)) -test(2377.5, any(grepl("^ncol:", capture.output(print(as.data.table(iris))))), FALSE, options=list(datatable.show.ncols=FALSE)) -test(2377.6, capture.output(print(as.data.table(iris), trunc.cols=TRUE, class=TRUE))[1L], "ncol: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]", options=list(width=10, datatable.show.ncols=TRUE)) +test(2377.4, capture.output(print(as.data.table(iris), trunc.cols=TRUE))[1L], "Number of columns: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]", options=list(width=10, datatable.show.ncols=TRUE)) +test(2377.5, any(grepl("^Number of columns:", capture.output(print(as.data.table(iris))))), FALSE, options=list(datatable.show.ncols=FALSE)) +test(2377.6, capture.output(print(as.data.table(iris), trunc.cols=TRUE, class=TRUE))[1L], "Number of columns: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]", options=list(width=10, datatable.show.ncols=TRUE)) From 0c69365f115d0f1034e0b40e10bac88689bfe323 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Thu, 25 Jun 2026 17:53:34 +0000 Subject: [PATCH 11/13] .. --- R/print.data.table.R | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index 477cc4b5c8..797f89d4a4 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -44,6 +44,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), if (!is.numeric(topn)) topn = 5L topnmiss = missing(topn) topn = max(as.integer(topn),1L) + show_trunc_message = isTRUE(trunc.cols) if (print.keys) { if (!is.null(ky <- key(x))) catf("Key: <%s>\n", toString(ky)) @@ -54,7 +55,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), )) } if (show.ncols && !isTRUE(trunc.cols) && !any(dim(x)==0L)) { - catf("Number of columns: %d\n", ncol(x)) + trunc_cols_message(character(0), NULL, FALSE, "none", ncol=ncol(x)) } if (any(dim(x)==0L)) { x_class = if (is.data.table(x)) "data.table" else "data.frame" # a data.frame could be passed to print.data.table() directly, #3363 @@ -126,31 +127,24 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), cols_to_print = widths < cons_width not_printed = colnames(toprint)[!cols_to_print] if (show.ncols) { - n_not_printed = length(not_printed) - if (n_not_printed > 0L) { - if (class && col.names != "none") classes = paste0(" ", tail(abbs, n_not_printed)) else classes = "" - catf("Number of columns: %d, of which %d %s not shown: %s\n", - ncol(x), n_not_printed, ngettext(n_not_printed, "is", "are"), - brackify(paste0(not_printed, classes))) - trunc.cols = FALSE - } else { - catf("Number of columns: %d\n", ncol(x)) + trunc_cols_message(not_printed, abbs, class, col.names, ncol=ncol(x)) + show_trunc_message = FALSE } - } + if (!any(cols_to_print)) { - if (!show.ncols) trunc_cols_message(not_printed, abbs, class, col.names) + if (show_trunc_message) trunc_cols_message(not_printed, abbs, class, col.names) return(invisible(x)) } # When nrow(toprint) = 1, attributes get lost in the subset, # function below adds those back when necessary toprint = toprint_subset(toprint, cols_to_print) - trunc.cols = !show.ncols && length(not_printed) > 0L + trunc.cols = length(not_printed) > 0L } print_default = function(x) { if (col.names != "none") cut_colnames = identity cut_colnames(print(x, right=TRUE, quote=quote, na.print=na.print)) # prints names of variables not shown in the print - if (trunc.cols) trunc_cols_message(not_printed, abbs, class, col.names) + if (show_trunc_message) trunc_cols_message(not_printed, abbs, class, col.names) } if (printdots) { if (isFALSE(row.names)) { @@ -307,14 +301,28 @@ toprint_subset = function(x, cols_to_print) { } } # message for when trunc.cols=TRUE and some columns are not printed -trunc_cols_message = function(not_printed, abbs, class, col.names){ +trunc_cols_message = function(not_printed, abbs, class, col.names, ncol=NULL){ n = length(not_printed) - if (class && col.names != "none") classes = paste0(" ", tail(abbs, n)) else classes = "" - catf( - ngettext(n, "%d variable not shown: %s\n", "%d variables not shown: %s\n"), - n, brackify(paste0(not_printed, classes)), - domain=NA - ) + if (is.null(ncol)) { + if (n == 0L) return() + if (class && col.names != "none") classes = paste0(" ", tail(abbs, n)) else classes = "" + catf( + ngettext(n, "%d variable not shown: %s\n", "%d variables not shown: %s\n"), + n, brackify(paste0(not_printed, classes)), + domain=NA + ) + } else { + if (n > 0L) { + if (class && col.names != "none") classes = paste0(" ", tail(abbs, n)) else classes = "" + catf( + ngettext(n, "Number of columns: %d, of which %d is not shown: %s\n", "Number of columns: %d, of which %d are not shown: %s\n"), + ncol, n, brackify(paste0(not_printed, classes)), + domain=NA + ) + } else { + catf("Number of columns: %d\n", ncol) + } + } } # Maybe add a method for repr::repr_text. See https://github.com/Rdatatable/data.table/issues/933#issuecomment-220237965 From 6757317ae3b0fa30705fd94e371447a173cfb183 Mon Sep 17 00:00:00 2001 From: venom1204 Date: Thu, 25 Jun 2026 18:27:45 +0000 Subject: [PATCH 12/13] added test --- inst/tests/tests.Rraw | 1 + 1 file changed, 1 insertion(+) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 474ca96e9a..7017b227ec 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21691,3 +21691,4 @@ test(2377.3, any(grepl("^[0-9]+ variables? not shown", capture.output(print(data test(2377.4, capture.output(print(as.data.table(iris), trunc.cols=TRUE))[1L], "Number of columns: 5, of which 5 are not shown: [Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species]", options=list(width=10, datatable.show.ncols=TRUE)) test(2377.5, any(grepl("^Number of columns:", capture.output(print(as.data.table(iris))))), FALSE, options=list(datatable.show.ncols=FALSE)) test(2377.6, capture.output(print(as.data.table(iris), trunc.cols=TRUE, class=TRUE))[1L], "Number of columns: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]", options=list(width=10, datatable.show.ncols=TRUE)) +test(2377.7, { dt = data.table(matrix(1:200, nrow=25)); out = capture.output(print(dt, trunc.cols=TRUE, class=TRUE)); grepl("", out[length(out)]) }, TRUE, options=list(width=30, datatable.show.ncols=TRUE)) From e697d454da2b75be2a041902ac0742a913d0d2dc Mon Sep 17 00:00:00 2001 From: venom1204 Date: Thu, 25 Jun 2026 20:30:59 +0000 Subject: [PATCH 13/13] test --- inst/tests/tests.Rraw | 1 + 1 file changed, 1 insertion(+) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 7017b227ec..2b2e857067 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21692,3 +21692,4 @@ test(2377.4, capture.output(print(as.data.table(iris), trunc.cols=TRUE))[1L], "N test(2377.5, any(grepl("^Number of columns:", capture.output(print(as.data.table(iris))))), FALSE, options=list(datatable.show.ncols=FALSE)) test(2377.6, capture.output(print(as.data.table(iris), trunc.cols=TRUE, class=TRUE))[1L], "Number of columns: 5, of which 5 are not shown: [Sepal.Length , Sepal.Width , Petal.Length , Petal.Width , Species ]", options=list(width=10, datatable.show.ncols=TRUE)) test(2377.7, { dt = data.table(matrix(1:200, nrow=25)); out = capture.output(print(dt, trunc.cols=TRUE, class=TRUE)); grepl("", out[length(out)]) }, TRUE, options=list(width=30, datatable.show.ncols=TRUE)) +test(2377.8, any(grepl("variable", capture.output(print(data.table(a=1), trunc.cols=TRUE)))), FALSE, options=list(width=80, datatable.show.ncols=FALSE))