Skip to content

Commit

Permalink
setorder can keep keys in more cases (#3458)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelChirico authored and mattdowle committed Apr 2, 2019
1 parent d54d3e0 commit 8e8db7c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
space for new columns) before adding new columns by reference to it.
```
3. `setorder` on a superset of a keyed `data.table`'s key now retains its key, [#3456](https://github.com/Rdatatable/data.table/issues/3456). For example, if `a` is the key of `DT`, `setorder(DT, a, -v)` will leave `DT` keyed by `a`.
### Changes in v1.12.2 (submitted to CRAN on 28 Mar 2019)
Expand Down
4 changes: 3 additions & 1 deletion R/setkey.R
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ setorderv <- function(x, cols = colnames(x), order=1L, na.last=FALSE)
if (is.data.frame(x) & !is.data.table(x)) {
setattr(x, 'row.names', rownames(x)[o])
}
setattr(x, 'sorted', NULL) # if 'forderv' is not 0-length, it means order has changed. So, set key to NULL, else retain key.
k = key(x)
if (!identical(head(cols, length(k)), k) || any(head(order, length(k)) < 0))
setattr(x, 'sorted', NULL) # if 'forderv' is not 0-length & key is not a same-ordered subset of cols, it means order has changed. So, set key to NULL, else retain key.
setattr(x, 'index', NULL) # remove secondary keys too. These could be reordered and retained, but simpler and faster to remove
}
invisible(x)
Expand Down
15 changes: 15 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -13971,6 +13971,21 @@ test(2020.09, DT[, prod(v), by=id], error="'complex' not supported by GForce pro
DT = data.table(id = c(1L,1L,2L,2L), v = c(1L, 2L, NA, NA))
test(2020.10, DT[, median(v), id], data.table(id=1:2, V1=c(1.5, NA))) # median whole group has NAs

# setorder can keep key if the order does not change, #3456
DT = data.table(
a = rep(4:1, 1:4),
b = 1:10,
v = c(2L, 4L, 10L, 5L, 9L, 6L, 7L, 8L, 3L, 1L)
)
setkey(DT, a)
setorder(DT, a, -v)
test(2021.1, key(DT), 'a')
setorder(DT, -a, v)
test(2021.2, key(DT), NULL)
setkey(DT, a, b)
setorder(DT, b)
test(2021.3, key(DT), NULL)


###################################
# Add new tests above this line #
Expand Down

0 comments on commit 8e8db7c

Please sign in to comment.