diff --git a/NEWS.md b/NEWS.md index 83d0c87134..4a62f35888 100644 --- a/NEWS.md +++ b/NEWS.md @@ -82,6 +82,8 @@ 19. `DT[order(double, ..., -non_double, na.last=TRUE)]`, i.e., a double/complex column (in any order) followed by a non-double column in descending order with `na.last=TRUE`, is fixed to respect `na.last` again, [#7875](https://github.com/Rdatatable/data.table/issues/7875). The problematic behavior only occurred under specific conditions on the cardinality of the non-double column. +20. `print.data.table()` now correctly displays data when `col.names="none"` and `row.names=FALSE`, [#7735](https://github.com/Rdatatable/data.table/issues/7735). Thanks to @jan-swissre for the report and @venom1204 for the fix. + ### Notes 1. {data.table} now depends on R 3.5.0 (2018). diff --git a/R/print.data.table.R b/R/print.data.table.R index 2aae182b09..f82a12cbab 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -131,8 +131,8 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), 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)) + if (col.names != "none") cut_colnames = function(x, nr) x + cut_colnames(print(x, right=TRUE, quote=quote, na.print=na.print), nrow(x)) # prints names of variables not shown in the print if (trunc.cols) trunc_cols_message(not_printed, abbs, class, col.names) } @@ -177,8 +177,13 @@ shouldPrint = function(x) { # for removing the head (column names) of matrix output entirely, # as opposed to printing a blank line, for excluding col.names per PR #1483 -# be sure to remove colnames from any row where they exist, #4270 -cut_colnames = function(x) writeLines(grepv("^\\s*(?:[0-9]+:|---)", capture.output(x))) +# print() splits a matrix too wide for the console into blocks, each one starting +# with its own line of column names; drop all of them, #4270, and don't rely on +# row names being present to identify the data lines, #7735 +cut_colnames = function(x, nr) { + out = capture.output(x) + writeLines(out[seq_along(out) %% (nr + 1L) != 1L]) +} # for printing the dims for list columns #3671; used by format.data.table() paste_dims = function(x) { diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index cc801ff6d4..eff85b13c4 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21912,3 +21912,16 @@ if (test_bit64) { DT_sorted[, i64 := as.integer64(i2)] test(2383.6, DT[order(d0, -i64, na.last=TRUE)], DT_sorted) } + +# col.names="none" should suppress only the column names, not the data, #7735 +DT = data.table(c1=1:2, c2=letters[1:2]) +test(2384.1, print(DT, col.names="none", row.names=FALSE, class=FALSE), output=c(" 1 a\n 2 b")) +# also handle wide tables and other formattings +DT = data.table(a=strrep("a",20L), b=strrep("b",20L), c=strrep("c",20L)) +test(2384.2, options=list(width=40L), print(DT, col.names="none", row.names=FALSE, class=FALSE), + output=c(" aaaaaaaaaaaaaaaaaaaa\n bbbbbbbbbbbbbbbbbbbb\n cccccccccccccccccccc")) +DT = data.table(x=c(NA,"e","b","j","w",NA)) +test(2384.3, print(DT, na.print=".", topn=2, col.names="none", row.names=FALSE, class=FALSE), + output=c(" .\n e\n ---\n w\n .")) +DT = data.table(a=c("x\ny","z"), b=1:2) +test(2384.4, print(DT, col.names="none", row.names=FALSE, class=FALSE), output=c(" x\\ny 1\n z 2"))