Skip to content

Commit c887a26

Browse files
authored
speed up slice_head() and slice_tail() (#219)
1 parent 6118f02 commit c887a26

File tree

3 files changed

+13
-15
lines changed

3 files changed

+13
-15
lines changed

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
* `filter()` works for negated logical columns (@mgirlich, @211).
55

6-
* speed up `slice_min()` and `slice_max()` after `group_by()` (@mgirlich, #216).
6+
* speed up `slice_*()` functions after `group_by()` (@mgirlich, #216).
77

88
* `slice_max()` now works when ordering by a character column (@mgirlich, #218).
99

R/step-subset-slice.R

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
#'
55
#' @description
66
#' These are methods for the dplyr [slice()], `slice_head()`, `slice_tail()`,
7-
#' `slice_min()`, `slice_max()` and `slice_sample()` generics. `slice()`
8-
#' and `slice_sample()` are translated to the `i` argument of `[.data.table`,
9-
#' all others are translated to the `j` argument.
7+
#' `slice_min()`, `slice_max()` and `slice_sample()` generics. They are
8+
#' translated to the `i` argument of `[.data.table`.
109
#'
1110
#' Unlike dplyr, `slice()` (and `slice()` alone) returns the same number of
1211
#' rows per group, regardless of whether or not the indices appear in each
@@ -80,11 +79,11 @@ slice.data.table <- function(.data, ...) {
8079
slice_head.dtplyr_step <- function(.data, ..., n, prop) {
8180
ellipsis::check_dots_empty()
8281
size <- check_slice_size(n, prop)
83-
j <- switch(size$type,
84-
n = expr(head(.SD, !!size$n)),
85-
prop = expr(head(.SD, !!size$prop * .N)),
82+
i <- switch(size$type,
83+
n = expr(seq.int(min(!!size$n, .N))),
84+
prop = expr(seq.int(!!size$prop * .N)),
8685
)
87-
step_subset_j(.data, j = j)
86+
step_subset_i(.data, i = i)
8887
}
8988

9089
#' @rdname slice.dtplyr_step
@@ -93,11 +92,11 @@ slice_head.dtplyr_step <- function(.data, ..., n, prop) {
9392
slice_tail.dtplyr_step <- function(.data, ..., n, prop) {
9493
ellipsis::check_dots_empty()
9594
size <- check_slice_size(n, prop)
96-
j <- switch(size$type,
97-
n = expr(tail(.SD, !!size$n)),
98-
prop = expr(tail(.SD, floor(!!size$prop * .N))),
95+
n_sequence <- switch(size$type,
96+
n = expr(min(!!size$n, .N)),
97+
prop = expr(!!size$prop * .N),
9998
)
100-
step_subset_j(.data, j = j)
99+
step_subset_i(.data, i = expr(seq.int(.N - !!n_sequence + 1, .N)))
101100
}
102101

103102
#' @rdname slice.dtplyr_step

man/slice.dtplyr_step.Rd

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)