From e86b16ea169df5c8f0e8c1cad5c44b55c6f1adae Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 26 Dec 2025 10:45:08 -0800 Subject: [PATCH 1/3] Set datatable.old.matrix.autoname to FALSE by default --- NEWS.md | 4 ++++ R/onLoad.R | 2 +- inst/tests/tests.Rraw | 38 ++++++++++++++------------------------ man/data.table-options.Rd | 2 +- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/NEWS.md b/NEWS.md index 28ef53c514..d362378d87 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,10 @@ ## data.table [v1.18.99](https://github.com/Rdatatable/data.table/milestone/37?closed=1) (in development) +### BREAKING CHANGES + +1. options `"datatable.old.matrix.autoname"` is now `FALSE` by default, meaning `names(data.table(x=1, cbind(1)))` is now `c("x", "V2")`. Toggle the option to retain the old behavior for now; future releases will work to remove this possibility. See the release notes for 1.18.0, item 1 under `NOTE OF INTENDED FUTURE POTENTIAL BREAKING CHANGES`. + ### Notes 1. {data.table} now depends on R 3.5.0 (2018). diff --git a/R/onLoad.R b/R/onLoad.R index 12cc93db1a..b72fee4d1b 100644 --- a/R/onLoad.R +++ b/R/onLoad.R @@ -98,7 +98,7 @@ datatable.auto.index=TRUE, # DT[col=="val"] to auto add index so 2nd time faster datatable.use.index=TRUE, # global switch to address #1422 datatable.prettyprint.char=NULL, # FR #1091 - datatable.old.matrix.autoname=TRUE # #7145: how data.table(x=1, matrix(1)) is auto-named set to change + datatable.old.matrix.autoname=FALSE # #7145: how data.table(x=1, matrix(1)) is auto-named set to change ) opts = opts[!names(opts) %chin% names(options())] options(opts) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 8b23e099aa..17b4173fb1 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21329,15 +21329,10 @@ if (test_R.utils) local({ }) # Create a data.table when one vector is transposed doesn't respect the name defined by user #4124 -local({ - old = options(datatable.old.matrix.autoname=FALSE) - on.exit(options(old)) - - test(2321.01, DT <- data.table(a=1:2, b=matrix(1:2)), data.table(a=1:2, b=1:2)) - test(2321.02, names(DT), names(data.frame(a=1:2, b=matrix(1:2)))) - test(2321.03, DT <- data.table(a=integer(), b=matrix(1L, nrow=0L, ncol=1L)), data.table(a=integer(), b=integer())) - test(2321.04, names(DT), names(data.frame(a=integer(), b=matrix(1L, nrow=0L, ncol=1L)))) -}) +test(2321.01, DT <- data.table(a=1:2, b=matrix(1:2)), data.table(a=1:2, b=1:2)) +test(2321.02, names(DT), names(data.frame(a=1:2, b=matrix(1:2)))) +test(2321.03, DT <- data.table(a=integer(), b=matrix(1L, nrow=0L, ncol=1L)), data.table(a=integer(), b=integer())) +test(2321.04, names(DT), names(data.frame(a=integer(), b=matrix(1L, nrow=0L, ncol=1L)))) ## but respect named column vectors test(2321.05, DT <- data.table(a=1:2, cbind(b=3:4)), data.table(a=1:2, b=3:4)) test(2321.06, names(DT), names(data.frame(a=1:2, cbind(b=3:4)))) @@ -21383,21 +21378,16 @@ M = cbind(1:3) test(2321.30, data.table(M[, 0L]), data.table(NULL)) test(2321.31, data.table(a=1:3, M[, 0L]), data.table(a=1:3)) -local({ - old = options(datatable.old.matrix.autoname=FALSE) - on.exit(options(old)) - - test(2321.32, names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V2", "c", "V4")) - # particularly buggy old behavior: can easily result in duplicate names - test(2321.33, names(data.table(cbind(1), cbind(2))), c("V1", "V2")) - M = cbind(1:3) - test(2321.34, data.table(M[, 0L]), data.table(NULL)) - test(2321.35, data.table(a=1:3, M[, 0L]), data.table(a=1:3)) - - # a more subtle version of this as expressed in #5367 - DT <- data.table(Counts=c(10, 20), Severity=c(1, 2)) - test(2321.36, names(DT[,.(New_name = Severity %*% Counts)]), "New_name") -}) +test(2321.32, names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V2", "c", "V4")) +# particularly buggy old behavior: can easily result in duplicate names +test(2321.33, names(data.table(cbind(1), cbind(2))), c("V1", "V2")) +M = cbind(1:3) +test(2321.34, data.table(M[, 0L]), data.table(NULL)) +test(2321.35, data.table(a=1:3, M[, 0L]), data.table(a=1:3)) + +# a more subtle version of this as expressed in #5367 +DT <- data.table(Counts=c(10, 20), Severity=c(1, 2)) +test(2321.36, names(DT[,.(New_name = Severity %*% Counts)]), "New_name") # New fctr() helper: like factor() but retaining order by default #4837 test(2322.01, levels(fctr(c("b","a","c"))), c("b","a","c")) diff --git a/man/data.table-options.Rd b/man/data.table-options.Rd index 63c79fdf6a..439e88ef2f 100644 --- a/man/data.table-options.Rd +++ b/man/data.table-options.Rd @@ -110,7 +110,7 @@ \section{Back-compatibility Options}{ \describe{ - \item{\code{datatable.old.matrix.autoname}}{Logical, default \code{TRUE}. Governs how the output of + \item{\code{datatable.old.matrix.autoname}}{Logical, default \code{FALSE}. Governs how the output of expressions like \code{data.table(x=1, cbind(1))} will be named. When \code{TRUE}, it will be named \code{V1}, otherwise it will be named \code{V2}. } From d9da10c80b2b8c8dc9b9d74de485288968834acc Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 26 Dec 2025 10:54:38 -0800 Subject: [PATCH 2/3] flip test option --- inst/tests/tests.Rraw | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 17b4173fb1..743ebc072a 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21370,9 +21370,14 @@ colnames(M) = c('A', '') test(2321.26, as.data.table(M), data.table(A=1:3, V2=4:6)) test(2321.27, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), A=1:3, V2=4:6)) -# also respect old auto-naming rules by default (to be deprecated) -test(2321.28, names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V1", "c", "V4")) -test(2321.29, names(data.table(cbind(1), cbind(2))), c("V1", "V1")) +local({ + old = options(datatable.old.matrix.autoname=TRUE) + on.exit(options(old)) + + # also respect old auto-naming rules by default (to be deprecated) + test(2321.28, names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V1", "c", "V4")) + test(2321.29, names(data.table(cbind(1), cbind(2))), c("V1", "V1")) +}) # also test behavior with a 0-column matrix M = cbind(1:3) test(2321.30, data.table(M[, 0L]), data.table(NULL)) From 8ceefda5e0e8bff9ae7a1e81d14391c373217417 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 26 Dec 2025 15:42:55 -0800 Subject: [PATCH 3/3] drop local() --- inst/tests/tests.Rraw | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 743ebc072a..35727c3b5f 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21370,14 +21370,11 @@ colnames(M) = c('A', '') test(2321.26, as.data.table(M), data.table(A=1:3, V2=4:6)) test(2321.27, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), A=1:3, V2=4:6)) -local({ - old = options(datatable.old.matrix.autoname=TRUE) - on.exit(options(old)) - - # also respect old auto-naming rules by default (to be deprecated) - test(2321.28, names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V1", "c", "V4")) - test(2321.29, names(data.table(cbind(1), cbind(2))), c("V1", "V1")) -}) +# also respect old auto-naming rules by default (to be deprecated) +test(2321.28, options=c(datatable.old.matrix.autoname=TRUE), + names(data.table(a=1, cbind(2), c=3, 4)), c("a", "V1", "c", "V4")) +test(2321.29, options=c(datatable.old.matrix.autoname=TRUE), + names(data.table(cbind(1), cbind(2))), c("V1", "V1")) # also test behavior with a 0-column matrix M = cbind(1:3) test(2321.30, data.table(M[, 0L]), data.table(NULL))