From 98474454bbe9af3d96b8eec5aa44f2946b44159d Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Thu, 13 May 2021 23:22:20 -0700 Subject: [PATCH] print(col.names="none") more robust (#4271) --- NEWS.md | 2 ++ R/print.data.table.R | 7 ++++--- inst/tests/tests.Rraw | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index f5badb48df..ae047be820 100644 --- a/NEWS.md +++ b/NEWS.md @@ -121,6 +121,8 @@ 14. `by=...get()...` could fail with `object not found`, [#4873](https://github.com/Rdatatable/data.table/issues/4873) [#4981](https://github.com/Rdatatable/data.table/issues/4981). Thanks to @sindribaldur for reporting, and @OfekShilon for fixing. +15. `print(x, col.names='none')` now removes the column names as intended for wide `data.table`s whose column names don't fit on a single line, [#4270](https://github.com/Rdatatable/data.table/issues/4270). Thanks to @tdhock for the report, and Michael Chirico for fixing. + ## NOTES 1. New feature 29 in v1.12.4 (Oct 2019) introduced zero-copy coercion. Our thinking is that requiring you to get the type right in the case of `0` (type double) vs `0L` (type integer) is too inconvenient for you the user. So such coercions happen in `data.table` automatically without warning. Thanks to zero-copy coercion there is no speed penalty, even when calling `set()` many times in a loop, so there's no speed penalty to warn you about either. However, we believe that assigning a character value such as `"2"` into an integer column is more likely to be a user mistake that you would like to be warned about. The type difference (character vs integer) may be the only clue that you have selected the wrong column, or typed the wrong variable to be assigned to that column. For this reason we view character to numeric-like coercion differently and will warn about it. If it is correct, then the warning is intended to nudge you to wrap the RHS with `as.()` so that it is clear to readers of your code that a coercion from character to that type is intended. For example : diff --git a/R/print.data.table.R b/R/print.data.table.R index 4f2ab7bf0e..4e666ca22e 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -114,7 +114,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), toprint = rbind(head(toprint, topn + isTRUE(class)), "---"="", tail(toprint, topn)) rownames(toprint) = format(rownames(toprint), justify="right") if (col.names == "none") { - cut_top(print(toprint, right=TRUE, quote=quote)) + cut_colnames(print(toprint, right=TRUE, quote=quote)) } else { print(toprint, right=TRUE, quote=quote) } @@ -129,7 +129,7 @@ print.data.table = function(x, topn=getOption("datatable.print.topn"), # option to shut this off per request of Oleg Bondar on SO, #1482 toprint=rbind(toprint, matrix(if (quote) old else colnames(toprint), nrow=1L)) # fixes bug #97 if (col.names == "none") { - cut_top(print(toprint, right=TRUE, quote=quote)) + cut_colnames(print(toprint, right=TRUE, quote=quote)) } else { print(toprint, right=TRUE, quote=quote) } @@ -192,7 +192,8 @@ 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 -cut_top = function(x) writeLines(capture.output(x)[-1L]) +# be sure to remove colnames from any row where they exist, #4270 +cut_colnames = function(x) writeLines(grep("^\\s*(?:[0-9]+:|---)", capture.output(x), value=TRUE)) # 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 3001616f90..9f2cafb3c5 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -17596,3 +17596,7 @@ DT = data.table(a=1L) test(2186, DT[, if (TRUE) .(a=1L) else .(a=1L, b=2L)], DT, warning='j may not evaluate to the same number of columns for each group') +# col.names='none' should apply when wrapping too, #4270 +DT = setDT(replicate(getOption('width'), 1, simplify = FALSE)) +test(2187, {print(DT, col.names='none'); TRUE}, notOutput="V") +