diff --git a/NEWS.md b/NEWS.md index 6d76838ced..09ad8fc38a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -70,7 +70,7 @@ 13. In rare cases, `data.table` failed to expand ALTREP columns when assigning a full column by reference. This could result in the target column getting modified unintentionally if the next call to the data.table was a modification by reference of the source column. E.g. in `DT[, b := as.character(a)]` the string conversion gets deferred and subsequent modification of column `a` would also modify column `b`, [#5400](https://github.com/Rdatatable/data.table/issues/5400). Thanks to @aquasync for the report and Václav Tlapák for the PR. -14. `data.table()` function is now more aligned with `data.frame()` with respect to the names of the output when one of its inputs is a single-column matrix object, [#4124](https://github.com/Rdatatable/data.table/issues/4124). Thanks @PavoDive for the report and @jangorecki for the PR. +14. `data.table()` function is now more aligned with `data.frame()` with respect to the names of the output when one of its inputs is a single-column matrix object, [#4124](https://github.com/Rdatatable/data.table/issues/4124). Thanks @PavoDive for the report, @jangorecki for the PR, and @MichaelChirico for a follow-up for back-compatibility. 15. Including an `ITime` object as a named input to `data.frame()` respects the provided name, i.e. `data.frame(a = as.ITime(...))` will have column `a`, [#4673](https://github.com/Rdatatable/data.table/issues/4673). Thanks @shrektan for the report and @MichaelChirico for the fix. diff --git a/R/as.data.table.R b/R/as.data.table.R index 38f99b80da..c68819450f 100644 --- a/R/as.data.table.R +++ b/R/as.data.table.R @@ -48,6 +48,9 @@ as.data.table.matrix = function(x, keep.rownames=FALSE, key=NULL, ...) { if (!identical(keep.rownames, FALSE)) { # can specify col name to keep.rownames, #575 ans = data.table(rn=rownames(x), x, keep.rownames=FALSE) + # auto-inferred name 'x' is not back-compatible & inconsistent, #7145 + if (ncol(x) == 1L && is.null(colnames(x))) + setnames(ans, 'x', 'V1') if (is.character(keep.rownames)) setnames(ans, 'rn', keep.rownames[1L]) return(ans) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 311b25ceaa..fcd0827010 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21276,13 +21276,46 @@ if (test_R.utils) local({ }) # Create a data.table when one vector is transposed doesn't respect the name defined by user #4124 -test(2321.1, DT <- data.table(a=1:2, b=matrix(1:2)), data.table(a=1:2, b=1:2)) -test(2321.2, names(DT), names(data.frame(a=1:2, b=matrix(1:2)))) -test(2321.3, DT <- data.table(a=integer(), b=matrix(1L, nrow=0L, ncol=1L)), data.table(a=integer(), b=integer())) -test(2321.4, 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.5, DT <- data.table(a=1:2, cbind(b=3:4)), data.table(a=1:2, b=3:4)) -test(2321.6, names(DT), names(data.frame(a=1:2, cbind(b=3:4)))) +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)))) +## also respect old naming pattern when invoked indirectly, #7145 +M = cbind(1:3) +test(2321.07, as.data.table(M), data.table(V1=1:3)) +rownames(M) = c('a', 'b', 'c') +test(2321.08, as.data.table(M), data.table(V1=1:3)) +test(2321.09, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), V1=1:3)) +colnames(M) = 'zz' +test(2321.10, as.data.table(M), data.table(zz=1:3)) +test(2321.11, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), zz=1:3)) +colnames(M) = 'x' +test(2321.12, as.data.table(M), data.table(x=1:3)) +test(2321.13, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), x=1:3)) +M = cbind(M, y=4:6) +test(2321.14, as.data.table(M), data.table(x=1:3, y=4:6)) +test(2321.15, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), x=1:3, y=4:6)) +colnames(M) = c('A', 'B') +test(2321.16, as.data.table(M), data.table(A=1:3, B=4:6)) +test(2321.17, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), A=1:3, B=4:6)) +colnames(M) = NULL +test(2321.18, as.data.table(M), data.table(V1=1:3, V2=4:6)) +test(2321.19, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), V1=1:3, V2=4:6)) +colnames(M) = c('x', '') +test(2321.20, as.data.table(M), data.table(x=1:3, V2=4:6)) +test(2321.21, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), x=1:3, V2=4:6)) +colnames(M) = c('', 'x') +test(2321.22, as.data.table(M), data.table(V1=1:3, x=4:6)) +test(2321.23, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), V1=1:3, x=4:6)) +colnames(M) = c('', '') +test(2321.24, as.data.table(M), data.table(V1=1:3, V2=4:6)) +test(2321.25, as.data.table(M, keep.rownames='id'), data.table(id=c('a', 'b', 'c'), V1=1:3, V2=4:6)) +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)) # New fctr() helper: like factor() but retaining order by default #4837 test(2322.01, levels(fctr(c("b","a","c"))), c("b","a","c"))