diff --git a/NEWS.md b/NEWS.md index eed4b7899b..4f521bdd2f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -341,7 +341,7 @@ 23. `fread(fill=TRUE, verbose=TRUE)` would segfault on the out-of-sample type bump verbose output if the input did not contain column names, [5046](https://github.com/Rdatatable/data.table/pull/5046). Thanks to Václav Tlapák for the PR. -24. `.SDcols=-V2:-V1` and `.SDcols=(-1)` could error with `xcolAns does not pass checks` and `argument specifying columns specify non existing column(s)`, [#4231](https://github.com/Rdatatable/data.table/issues/4231). Thanks to Jan Gorecki for reporting and the PR. +24. `.SDcols=-V2:-V1` and `.SDcols=(-1)` could error with `xcolAns does not pass checks` and `argument specifying columns specify non existing column(s)`, [#4231](https://github.com/Rdatatable/data.table/issues/4231). Thanks to Jan Gorecki for reporting and the PR. Thanks Toby Dylan Hocking for tracking down an error caused by the initial fix and Michael Chirico for fixing it. 25. `.SDcols=` is now documented in `?data.table` and it is now an error if the logical vector's length is not equal to the number of columns (consistent with `data.table`'s no-recycling policy; see new feature 1 in v1.12.2 Apr 2019), [#4115](https://github.com/Rdatatable/data.table/issues/4115). Thanks to @Henrik-P for reporting and Jan Gorecki for the PR. diff --git a/R/data.table.R b/R/data.table.R index 130543cbbc..76e6c4e0e0 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -1008,7 +1008,8 @@ replace_dot_alias = function(e) { # peel from parentheses before negation so (-1L) works as well: as.data.table(as.list(1:3))[, .SD,.SDcols=(-1L)] #4231 while(colsub %iscall% "(") colsub = as.list(colsub)[[-1L]] # fix for R-Forge #5190. colsub[[1L]] gave error when it's a symbol. - if (colsub %iscall% c("!", "-")) { + # NB: _unary_ '-', not _binary_ '-' (#5826). Test for '!' length-2 should be redundant but low-cost & keeps code concise. + if (colsub %iscall% c("!", "-") && length(colsub) == 2L) { negate_sdcols = TRUE colsub = colsub[[2L]] } else negate_sdcols = FALSE diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 500aa30a97..f27abfcc0c 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18179,3 +18179,8 @@ DT = data.table(id=1:2, x=1:2) r = copy(DT)[1L, x:= 5L] test(2241.13, DT, data.table(id=1:2, x=1:2)) test(2241.14, r, data.table(id=1:2, x=c(5L,2L))) + +# .SDcols using binary '-' is evaluated correctly (#5826 exposed this) +DT = data.table(a=1, b=2, c=3) +test(2242.1, DT[, .SD, .SDcols=2-1], DT[, .(a)]) +test(2242.2, DT[, .SD, .SDcols=length(DT)-1], DT[, .SD, .SDcols=2])