Giter Club home page Giter Club logo

Comments (5)

hadley avatar hadley commented on June 14, 2024

Can more efficiently implement this (for the default case where default is a missing value) by using vec_slice(x, c(NA, idx)) etc.

from funs.

DavisVaughan avatar DavisVaughan commented on June 14, 2024

Adding a note that pmin() is much slower than min(). I don't think we need it here

bench::mark(pmin(1, 2), min(1, 2))
#> # A tibble: 2 x 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 pmin(1, 2)   4.71µs   5.49µs   178269.    80.8KB     107.
#> 2 min(1, 2)     232ns    341ns  2773155.        0B       0

Created on 2020-02-11 by the reprex package (v0.3.0)

from funs.

hadley avatar hadley commented on June 14, 2024

And consider unify into a single function, as in tidyverse/dplyr#5260

from funs.

DavisVaughan avatar DavisVaughan commented on June 14, 2024

shift()

from funs.

DavisVaughan avatar DavisVaughan commented on June 14, 2024

Potential full implementation using vec_shift() as the base for vec_lag() and vec_lead() (we can drop the vec_)

library(vctrs)
library(rlang)

vec_lag <- function(x, n = 1L, default = NULL, order_by = NULL) {
  vec_assert(n, size = 1L, arg = "n")
  n <- vec_cast(n, integer(), x_arg = "n")
  
  if (n < 0L) {
    abort("`n` must be positive.")
  }
  
  vec_shift(x, n, default, order_by)
}

vec_lead <- function(x, n = 1L, default = NULL, order_by = NULL) {
  vec_assert(n, size = 1L, arg = "n")
  n <- vec_cast(n, integer(), x_arg = "n")
  
  if (n < 0L) {
    abort("`n` must be positive.")
  }
  
  n <- n * -1L
  
  vec_shift(x, n, default, order_by)
}

vec_shift <- function(x, n = 1L, default = NULL, order_by = NULL) {
  size <- vec_size(x)
  
  if (!is.null(order_by)) {
    out <- with_order(x, order_by, size, vec_shift, n = n, default = default)
    return(out)
  }
  
  vec_assert(n, size = 1L, arg = "n")
  n <- vec_cast(n, integer(), x_arg = "n")
  
  if (identical(n, 0L)) {
    return(x)
  }
  
  lag <- sign(n) > 0L
  n <- abs(n)
  
  if (n > size) {
    n <- size
  }
  
  if (is.null(default)) {
    vec_shift_slice(x, n, size, lag)
  } else {
    vec_shift_c(x, n, size, lag, default)
  }
}

vec_shift_slice <- function(x, n, size, lag) {
  idx_default <- vec_rep(NA_integer_, n)
  
  if (lag) {
    idx <- seq2(1L, size - n)
    idx <- c(idx_default, idx)
    vec_slice(x, idx)
  } else {
    idx <- seq2(1L + n, size)
    idx <- c(idx, idx_default)
    vec_slice(x, idx)
  }
}

vec_shift_c <- function(x, n, size, lag, default) {
  vec_assert(default, size = 1L, arg = "default")
  default <- vec_cast(default, x, x_arg = "default")
  
  default <- vec_rep(default, n)
  
  if (lag) {
    idx <- seq2(1L, size - n)
    x <- vec_slice(x, idx)
    vec_c(default, x)
  } else {
    idx <- seq2(1L + n, size)
    x <- vec_slice(x, idx)
    vec_c(x, default)
  }
}

with_order <- function(.x, .order_by, .size, .fn, ...) {
  vec_assert(.order_by, size = .size)
  o <- vec_order(.order_by)
  x <- vec_slice(.x, o)
  out <- .fn(x, ...)
  vec_slice(out, vec_order(o))
}

Also fixes two issues with current dplyr version:

# shouldnt return size 1
dplyr::lag(1:5, order_by = 1)
#> [1] NA

vec_lag(1:5, order_by = 1)
#> Error: `.order_by` must have size 5, not size 1.

# should cast default->x, not take common type
class(dplyr::lag(1:5, default = NA_real_))
#> [1] "numeric"

class(vec_lag(1:5, default = NA_real_))
#> [1] "integer"

from funs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.