diff --git a/NEWS.md b/NEWS.md index a7db78c3fb..81dd36e1de 100644 --- a/NEWS.md +++ b/NEWS.md @@ -76,6 +76,8 @@ 16. `fread()` now handles the `na.strings` argument for quoted text columns, making it possible to specify `na.strings = '""'` and read empty quoted strings as `NA`s, [#6974](https://github.com/Rdatatable/data.table/issues/6974). Thanks to @AngelFelizR for the report and @aitap for the PR. +17. A data.table with a column of class `vctrs_list_of` (from package {vctrs}) prints as expected, [#5948](https://github.com/Rdatatable/data.table/issues/5948). Before, they could be printed messily, e.g. printing every entry in a nested data.frame. Thanks @jesse-smith for the report, @DavisVaughan and @r2evans for contributing, and @MichaelChirico for the PR. + ### NOTES 1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/. diff --git a/R/print.data.table.R b/R/print.data.table.R index 263e283d70..3e93eb3f81 100644 --- a/R/print.data.table.R +++ b/R/print.data.table.R @@ -199,8 +199,6 @@ has_format_method = function(x) { format_col.default = function(x, ...) { if (!is.null(dim(x))) "" - else if (has_format_method(x) && length(formatted<-format(x, ...))==length(x)) - formatted #PR5224 motivated by package sf where column class is c("sfc_MULTIPOLYGON","sfc") and sf:::format.sfc exists else if (is.list(x)) vapply_1c(x, format_list_item, ...) else diff --git a/inst/tests/other.Rraw b/inst/tests/other.Rraw index 720ddf1945..ccd2ffdc88 100644 --- a/inst/tests/other.Rraw +++ b/inst/tests/other.Rraw @@ -1,4 +1,4 @@ -pkgs = c("ggplot2", "hexbin", "plyr", "dplyr", "caret", "zoo", "xts", "gdata", "nlme", "bit64", "knitr", "parallel", "sf", "nanotime", "R.utils", "yaml") +pkgs = c("bit64", "caret", "dplyr", "gdata", "ggplot2", "hexbin", "knitr", "nanotime", "nlme", "parallel", "plyr", "R.utils", "sf", "vctrs", "xts", "yaml", "zoo") # First expression of this file must be as above: .gitlab-ci.yml uses parse(,n=1L) to read one expression from this file and installs pkgs. # So that these dependencies of other.Rraw are maintained in a single place. # TEST_DATA_TABLE_WITH_OTHER_PACKAGES is off by default so this other.Rraw doesn't run on CRAN. It is run by GLCI, locally in dev, and by @@ -221,6 +221,7 @@ test(14.2, {example('CJ', package='data.table', local=TRUE, echo=FALSE); TRUE}) if (loaded[["sf"]]) { #2273 DT = as.data.table(st_read(system.file("shape/nc.shp", package = "sf"), quiet=TRUE)) test(15, DT[1:3, .(NAME, FIPS, geometry)], output="Ashe.*-81.4.*Surry.*-80.4") + test(15.1, DT, output="MULTIPOLYGON (((") # make sure individual list items are formatted, #6637, #5224 dsf = sf::st_as_sf(data.table(x=1:10, y=1:10, s=sample(1:2, 10, TRUE)), coords=1:2) test(16, split(dsf, dsf$s), list(`1` = dsf[dsf$s == 1, ], `2` = dsf[dsf$s == 2, ])) @@ -774,3 +775,9 @@ if (loaded[["nanotime"]]) { res <- tables(env=.e) test(32, res[, .(NAME,NROW,NCOL,MB)], data.table(NAME="DT",NROW=20000000L,NCOL=15L,MB=2288.0)) rm(.e, res) + +if (loaded[["vctrs"]]) { + # vctrs::list_of() columns are treated the same as other list() columns + DT = data.table(a = 1, b = list_of(mtcars)) + test(33, DT, output=".*") +} diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 07702ff847..35ece3b4a4 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -16800,7 +16800,7 @@ registerS3method("format_col", "complex", format_col.default) # then i) test 1610.1 fails if test.data.table() is rerun, ii) user display of complex data would be affected # did try wrapping with on.exit(,add=TRUE) but perhaps because this is a script that is sys.source'd, it ran straight away -# format method for column takes predecedence over format method for each list item +# as of #6637, format individual list items but not the whole list registerS3method("format", "myclass2130", function(x, ...) paste0("<", class(x)[1L], ":", x$id, ">")) DT = data.table(row=1:2, objs=list(structure(list(id="foo"), class="myclass2130"), structure(list(id="bar"), class="myclass2130"))) test(2130.13, print(DT), output="myclass2130:foo.*myclass2130:bar") @@ -16808,7 +16808,7 @@ setattr(DT$objs, "class", "foo2130") registerS3method("format", "foo2130", function(x, ...) "All hail foo") test(2130.14, print(DT), output="myclass2130:foo.*myclass2130:bar") # because length 1 from format but needs to be length(x) registerS3method("format", "foo2130", function(x, ...) rep("All hail foo",length(x))) -test(2130.15, print(DT), output="All hail foo") # e.g. sf:::format.sfc rather than sf:::format.sfg on each item +test(2130.15, print(DT), output="myclass2130:foo.*myclass2130:bar") # used to call format(column), not vapply_1c(column, format) setattr(DT$objs, "class", "bar2130_with_no_method") test(2130.16, print(DT), output="myclass2130:foo.*myclass2130:bar") registerS3method("format", "myclass2130", format.default)