From d9b7ad5bd583662585032c87afb6ec6aaa5a2b21 Mon Sep 17 00:00:00 2001 From: Tyson Barrett Date: Thu, 2 Jan 2020 19:09:00 -0700 Subject: [PATCH] Print list-column dims (#4154) --- NEWS.md | 2 ++ R/print.data.table.R | 12 +++++++++++- inst/tests/tests.Rraw | 36 +++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index c8317153c..f369d17ff 100644 --- a/NEWS.md +++ b/NEWS.md @@ -71,6 +71,8 @@ unit = "s") 9. `rbindlist` now supports columns of type `expression`, [#546](https://github.com/Rdatatable/data.table/issues/546). Thanks @jangorecki for the report. +10. The dimensions of objects in a `list` column are now displayed, [#3671](https://github.com/Rdatatable/data.table/issues/3671). Thanks to @randomgambit for the request, and Tyson Barrett for the PR. + ## BUG FIXES 1. A NULL timezone on POSIXct was interpreted by `as.IDate` and `as.ITime` as UTC rather than the session's default timezone (`tz=""`) , [#4085](https://github.com/Rdatatable/data.table/issues/4085). diff --git a/R/print.data.table.R b/R/print.data.table.R index 9bba978f0..ba17e5888 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -145,7 +145,7 @@ format.data.table = function (x, ..., justify="none", timezone = FALSE) { else if (is.atomic(x) || inherits(x,"formula")) # FR #2591 - format.data.table issue with columns of class "formula" paste(c(format(head(x, 6L), justify=justify, ...), if (length(x) > 6L) "..."), collapse=",") # fix for #5435 - format has to be added here... else - paste0("<", class(x)[1L], ">") + paste0("<", class(x)[1L], paste_dims(x), ">") } # FR #2842 add timezone for posix timestamps format.timezone = function(col) { # paste timezone to a time object @@ -189,6 +189,16 @@ shouldPrint = function(x) { # as opposed to printing a blank line, for excluding col.names per PR #1483 cut_top = function(x) cat(capture.output(x)[-1L], sep = '\n') +# for printing the dims for list columns #3671; used by format.data.table() +paste_dims = function(x) { + dims = if (isS4(x)) { + length(slotNames(x)) + } else { + if (is.null(dim(x))) length(x) else dim(x) + } + paste0("[", paste(dims,collapse="x"), "]") +} + # to calculate widths of data.table for PR #4074 # gets the width of the data.table at each column # and compares it to the console width diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 6e1387585..3233c4f94 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -1631,7 +1631,7 @@ test(557, DT[, f(.SD), by=x], error="[.]SD is locked.*reserved for possible futu # Test printing on nested data.table, bug #1803 DT = data.table(x=letters[1:3], y=list(1:10, letters[1:4], data.table(a=1:3,b=4:6))) test(558, capture.output(print(DT)), - c(" x y", "1: a 1,2,3,4,5,6,...", "2: b a,b,c,d", "3: c ")) + c(" x y", "1: a 1,2,3,4,5,6,...", "2: b a,b,c,d", "3: c ")) test(559, setkey(DT,x)["a",y][[1]], 1:10) # y is symbol representing list column, specially detected in dogroups # Test renaming of .N to N @@ -8280,11 +8280,11 @@ DT1 = data.table(lcol = list(list(1:3), list(1:3), list(1:3)), xcol = as.complex(icol), ocol = factor(icol, ordered = TRUE), fcol = factor(icol)) test(1610.1, capture.output(print(DT1, class=TRUE)), - c(" lcol icol ncol ccol xcol ocol fcol", - " ", - "1: 1 1 a 1+0i 1 1", - "2: 2 2 b 2+0i 2 2", - "3: 3 3 c 3+0i 3 3")) + c(" lcol icol ncol ccol xcol ocol fcol", + " ", + "1: 1 1 a 1+0i 1 1", + "2: 2 2 b 2+0i 2 2", + "3: 3 3 c 3+0i 3 3")) DT2 = data.table( Dcol = as.Date('2016-01-01') + 0:2, Pcol = as.POSIXct('2016-01-01 01:00:00', tz = 'UTC') + 86400L*(0:2), @@ -8872,13 +8872,13 @@ test(1635.2, fread(text, fill=TRUE), setnames(ans1[, 1:7], c(letters[1:5], paste # testing function type in dt, #518 dt = data.table(x=1, y=sum) test(1636.1, class(dt$y), "list") -test(1636.2, any(grepl("1: 1 ", capture.output(print(dt)))), TRUE) +test(1636.2, print(dt), output="1: 1 ") dt = data.table(x=1:2, y=sum) test(1636.3, class(dt$y), "list") -test(1636.4, any(grepl("2: 2 ", capture.output(print(dt)))), TRUE) +test(1636.4, print(dt), output="2: 2 ") dt = data.table(x=1:2, y=c(sum, min)) test(1636.5, class(dt$y), "list") -test(1636.6, any(grepl("2: 2 ", capture.output(print(dt)))), TRUE) +test(1636.6, print(dt), output="2: 2 ") # #484 fix (related to #495 fix above) dt = data.table(a = 1, b = 1) @@ -16708,6 +16708,24 @@ A = data.table(c1 = 1, c2 = 'asd', c3 = expression(as.character(Sys.time()))) B = data.table(c1 = 3, c2 = 'qwe', c3 = expression(as.character(Sys.time()+5))) test(2129, rbind(A,B)$c3, expression(as.character(Sys.time()), as.character(Sys.time()+5))) +# print dims in list-columns, #3671 +DT = data.table( + x = 1:2, + y = list(data.table(x=1, y=1), + data.table(x=2, y=2))) +test(2130.01, print(DT), output=c(" x y", "1: 1 ", "2: 2 ")) +DT = data.table( + x = 1:2, + y = list(list(x=1, y=c("yes", "no")), + list(x=2, y=2))) +test(2130.02, print(DT), output=c(" x y", "1: 1 ", "2: 2 ")) +s4class = setClass("ex_class", slots = list(x="integer", y="character", z="numeric")) +DT = data.table( + x = 1:2, + y = list(s4class(x=1L, y=c("yes", "no"), z=2.5), + s4class(x=2L, y="yes", z=1))) +test(2130.03, print(DT), output=c(" x y", "1: 1 ", "2: 2 ")) + ######################## # Add new tests here #