Skip to content

Commit

Permalink
setDT generates shallow copy earlier to avoid interfering with attrib…
Browse files Browse the repository at this point in the history
…utes of co-bound tables (#6551)

* Fix #4784: setDT inside a function no longer modifies the class of the data.frame argument

* data.table style

* Add a second, "dumb" test for completeness

* Run setalloccol before _any_ set* affects original table

* New test of row.names issue for moving setalloccol up

* Directly call .shallow to keep selfrefok() in other tests

* trailing ws

* NEWS wording & improvement

* Improve comment wording

* Shrink ws diff

---------

Co-authored-by: Ofek Shilon <[email protected]>
  • Loading branch information
MichaelChirico and OfekShilon authored Oct 1, 2024
1 parent d62aac9 commit b4538a0
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
8 changes: 8 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -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))

0 comments on commit b4538a0

Please sign in to comment.