diff --git a/NEWS.md b/NEWS.md index 4bf066f417..eb31baf576 100644 --- a/NEWS.md +++ b/NEWS.md @@ -111,6 +111,8 @@ rowwiseDT( 13. Restore some join operations on `x` and `i` (e.g. an anti-join `x[!i]`) where `i` is an extended data.frame, but not a data.table (e.g. a `tbl`), [#6501](https://github.com/Rdatatable/data.table/issues/6501). Thanks @MichaelChirico for the report and PR. +14. `setDT()` no longer modifies the class of other names bound to the origin data.frame, e.g., in `DF1 <- data.frame(a=1); DF2 <- DF1; setDT(DF2)`, `DF1`'s class will not change. [#4784](https://github.com/Rdatatable/data.table/issues/4784). Thanks @OfekShilon for the report and fix. + ## NOTES 1. Tests run again when some Suggests packages are missing, [#6411](https://github.com/Rdatatable/data.table/issues/6411). Thanks @aadler for the note and @MichaelChirico for the fix. diff --git a/R/data.table.R b/R/data.table.R index 7b48704a1a..d0b940ae15 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -2922,6 +2922,10 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) { break } } + + # Done to avoid affecting other copies of x when we setattr() below (#4784) + x = .shallow(x) + rn = if (!identical(keep.rownames, FALSE)) rownames(x) else NULL setattr(x, "row.names", .set_row_names(nrow(x))) if (check.names) setattr(x, "names", make.names(names(x), unique=TRUE)) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 89bca1bea4..f79bec0d7f 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -20583,3 +20583,11 @@ test(2294.72, character(0)), label = list(character = "C3", VCharA = "Total", integer = 2L))), warning = "For the following variables, the 'label' value was already in the data: [VCharB (label: C3), VIntA (label: 2)]") + +# setDT no longer leaks class modification to origin copy, #4784 +d1 = data.frame(a=1, row.names='b') +d2 = d1 +setDT(d2) +test(2295.1, !is.data.table(d1)) +test(2295.2, rownames(d1), 'b') +test(2295.3, is.data.table(d2))