File: verb-window.R

package info (click to toggle)
r-cran-dbplyr 2.3.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,376 kB
  • sloc: sh: 13; makefile: 2
file content (64 lines) | stat: -rw-r--r-- 1,739 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#' Override window order and frame
#'
#' These allow you to override the `PARTITION BY` and `ORDER BY` clauses
#' of window functions generated by grouped mutates.
#'
#' @inheritParams arrange.tbl_lazy
#' @param ... Variables to order by
#' @export
#' @examples
#' library(dplyr, warn.conflicts = FALSE)
#'
#' db <- memdb_frame(g = rep(1:2, each = 5), y = runif(10), z = 1:10)
#' db %>%
#'   window_order(y) %>%
#'   mutate(z = cumsum(y)) %>%
#'   show_query()
#'
#' db %>%
#'   group_by(g) %>%
#'   window_frame(-3, 0) %>%
#'   window_order(z) %>%
#'   mutate(z = sum(y)) %>%
#'   show_query()
window_order <- function(.data, ...) {
  if (!is_tbl_lazy(.data)) {
    msg <- "{.arg .data} must be a {.cls tbl_lazy}, not a {.cls {class(.data)}}."
    if (is.data.frame(.data)) {
      msg <- c(msg, i = "Did you mean to use {.fn arrange} instead?")
    }
    cli_abort(msg)
  }
  dots <- partial_eval_dots(.data, ..., .named = FALSE)
  names(dots) <- NULL

  .data$lazy_query <- add_order(.data, dots)
  .data
}

# We want to preserve this ordering (for window functions) without
# imposing an additional arrange, so we have a special op_order
add_order <- function(.data, dots) {
  .data$lazy_query$order_vars <- dots
  .data$lazy_query
}


# Frame -------------------------------------------------------------------

#' @export
#' @rdname window_order
#' @param from,to Bounds of the frame.
window_frame <- function(.data, from = -Inf, to = Inf) {
  if (!is_tbl_lazy(.data)) {
    cli_abort(
      "{.arg .data} must be a {.cls tbl_lazy}, not a {.cls {class(.data)}}."
    )
  }

  stopifnot(is.numeric(from), length(from) == 1)
  stopifnot(is.numeric(to), length(to) == 1)

  .data$lazy_query$frame <- list(range = c(from, to))
  .data
}