Skip to content

Make vec_slice() size-aware #2171

Description

@jameslairdsmith

An idea for making vec_slice() aware of the size of the vector. One way to do this would be similar to what happens in dplyr, where there is n(), which in this case would only work inside the call to vec_slice().

library(vctrs)

vec_slice_n <- function(x, i, ...) {                                          
  i_quo <- substitute(i)                                                      
  size <- vctrs::vec_size(x)                                                  
  mask <- new.env(parent = parent.frame())                                    
  mask$n <- function() size   
  idx <- eval(i_quo, envir = mask)                                            
  vctrs::vec_slice(x, idx, ...)                                               
}

vec_slice_n(letters, n())            
#> [1] "z"
vec_slice_n(letters, c(1, n()))      
#> [1] "a" "z"
vec_slice_n(letters, (n() - 2):n())  
#> [1] "x" "y" "z"
vec_slice_n(letters, -n())  
#>  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
#> [20] "t" "u" "v" "w" "x" "y"

 `vec_slice_n<-` <- function(x, i, ..., value) {
   i_quo <- substitute(i)
   size <- vctrs::vec_size(x) 
   mask <- new.env(parent = parent.frame())
   mask$n <- function() size
   idx <- eval(i_quo, envir = mask)
   vctrs::`vec_slice<-`(x, idx, ..., value = value)
}

y <- 1:5; vec_slice_n(y, n()) <- 99; y            
#> [1]  1  2  3  4 99
z <- 1:5; vec_slice_n(z, c(1, n())) <- c(-1,-9); z 
#> [1] -1  2  3  4 -9
w <- 1:5; k <- 2; vec_slice_n(w, (n()-k):n()) <- 0; w
#> [1] 1 2 0 0 0

Created on 2026-06-30 with reprex v2.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions