From e13e8b3faf2bb530e20b11d3f808eb4ba9c025bf Mon Sep 17 00:00:00 2001 From: TysonStanley Date: Tue, 31 Dec 2019 12:44:53 -0700 Subject: [PATCH 1/5] add list-column dims to print --- R/print.data.table.R | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index 9bba978f02..21dc523395 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 +# is used in format.data.table() +paste_dims = function(x) { + dims = dim(x) + if (is.null(dims)) + dims = length(x) + dims = paste(dims, collapse="x") + paste0("[", dims, "]") +} + # 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 From 2367b015beb844cc1fa73b4998bf16aae2ec777d Mon Sep 17 00:00:00 2001 From: TysonStanley Date: Tue, 31 Dec 2019 12:49:04 -0700 Subject: [PATCH 2/5] added tests for printing list-column dims --- inst/tests/tests.Rraw | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 6e1387585f..e85baf3aa5 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -16708,6 +16708,27 @@ 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::data.table( + x = 1:2, + y = list(data.table(x = 1, + y = 1), + data.table(x = 2, + y = 2))) +test(2130.01, capture.output(print(DT)), + c(" x y", + "1: 1 ", + "2: 2 ")) +DT = data.table::data.table( + x = 1:2, + y = list(list(x = 1, + y = c("yes", "no")), + list(x = 2, + y = 2))) +test(2130.02, capture.output(print(DT)), + c(" x y", + "1: 1 ", + "2: 2 ")) ######################## # Add new tests here # From 76497938f020a049494097d589752191369fa47f Mon Sep 17 00:00:00 2001 From: TysonStanley Date: Tue, 31 Dec 2019 13:35:28 -0700 Subject: [PATCH 3/5] fix tests that print list-columns with dimensions --- inst/tests/tests.Rraw | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index e85baf3aa5..3aeec93668 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, any(grepl("1: 1 ", capture.output(print(dt)))), TRUE) 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, any(grepl("2: 2 ", capture.output(print(dt)))), TRUE) 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, any(grepl("2: 2 ", capture.output(print(dt)))), TRUE) # #484 fix (related to #495 fix above) dt = data.table(a = 1, b = 1) From 0f47bc46fd1072cbe10f13d8e61452689fda6057 Mon Sep 17 00:00:00 2001 From: TysonStanley Date: Wed, 1 Jan 2020 17:02:45 -0700 Subject: [PATCH 4/5] added print for list-column dimension for s4 classes --- R/print.data.table.R | 11 ++++++++--- inst/tests/tests.Rraw | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/R/print.data.table.R b/R/print.data.table.R index 21dc523395..eb32d5dde4 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -192,9 +192,14 @@ cut_top = function(x) cat(capture.output(x)[-1L], sep = '\n') # for printing the dims for list columns #3671 # is used in format.data.table() paste_dims = function(x) { - dims = dim(x) - if (is.null(dims)) - dims = length(x) + if (isS4(x)) { + dims = length(slotNames(x)) + } else { + dims = dim(x) + if (is.null(dims)) + dims = length(x) + } + dims = paste(dims, collapse="x") paste0("[", dims, "]") } diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 3aeec93668..5b84f34e53 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -16729,6 +16729,23 @@ test(2130.02, capture.output(print(DT)), c(" x y", "1: 1 ", "2: 2 ")) +s4class <- setClass("ex_class", + slots = list(x = "integer", + y = "character", + z = "numeric")) +DT = data.table::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, capture.output(print(DT)), + c(" x y", + "1: 1 ", + "2: 2 ")) + ######################## # Add new tests here # From f6d6960708a3afbf2c4e5f6b4875ba539edb35db Mon Sep 17 00:00:00 2001 From: mattdowle Date: Thu, 2 Jan 2020 17:53:26 -0800 Subject: [PATCH 5/5] tidy and added news item --- NEWS.md | 2 ++ R/print.data.table.R | 15 ++++-------- inst/tests/tests.Rraw | 54 ++++++++++++++----------------------------- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/NEWS.md b/NEWS.md index c8317153c2..f369d17ff7 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 eb32d5dde4..ba17e5888d 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -189,19 +189,14 @@ 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 -# is used in format.data.table() +# for printing the dims for list columns #3671; used by format.data.table() paste_dims = function(x) { - if (isS4(x)) { - dims = length(slotNames(x)) + dims = if (isS4(x)) { + length(slotNames(x)) } else { - dims = dim(x) - if (is.null(dims)) - dims = length(x) + if (is.null(dim(x))) length(x) else dim(x) } - - dims = paste(dims, collapse="x") - paste0("[", dims, "]") + paste0("[", paste(dims,collapse="x"), "]") } # to calculate widths of data.table for PR #4074 diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 5b84f34e53..3233c4f94b 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -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,43 +16708,23 @@ 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::data.table( +# 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, capture.output(print(DT)), - c(" x y", - "1: 1 ", - "2: 2 ")) -DT = data.table::data.table( + 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, capture.output(print(DT)), - c(" x y", - "1: 1 ", - "2: 2 ")) -s4class <- setClass("ex_class", - slots = list(x = "integer", - y = "character", - z = "numeric")) -DT = data.table::data.table( + 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, capture.output(print(DT)), - c(" x y", - "1: 1 ", - "2: 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 ")) ########################