Home > Mobile >  Sequence with different intervals
Sequence with different intervals

Time:12-24

seq can only use a single value in the by parameter. Is there a way to vectorize by, i.e. to use multiple intervals?

Something like this:

seq(1, 10, by = c(1, 2))

would return c(1, 2, 4, 5, 7, 8, 10). Now, this is possible to do this with e.g. seq(1, 10, by = 1)[c(T, T, F)] because it's a simple case, but is there a way to make it generalizable to more complex sequences?

Some examples

seq(1, 100, by = 1:5)
#[1] 1 2 4 7 11 16 17 19 22 26 31...

seq(8, -5, by = c(3, 8))
#[1] 8 5 -3

CodePudding user response:

This doesn't seem possible Maël. I suppose it's easy enough to write one?

seq2 <- function(from, to, by) {
  
  vals <- c(0, cumsum(rep(by, abs(ceiling((to - from) / sum(by))))))
  if(from > to) return((from - vals)[(from - vals) >= to])
  else (from   vals)[(from   vals) <= to]
}

Testing:

seq2(1, 10, by = c(1, 2))
#> [1]  1  2  4  5  7  8 10

seq2(1, 100, by = 1:5)
#>  [1]  1  2  4  7 11 16 17 19 22 26 31 32 34 37 41 46 47 49 52 56 61 62 64 67 71
#> [26] 76 77 79 82 86 91 92 94 97

seq2(8, -5, by = c(3, 8))
#> [1]  8  5 -3

Created on 2022-12-23 with reprex v2.0.2

CodePudding user response:

this looks like a close base R solution?

ans <- Reduce(` `, rep(1:5, 100), init = 1, accumulate = TRUE)
ans[1:(which.max(ans >= 100) - 1)]

[1]  1  2  4  7 11 16 17 19 22 26 31 32 34 37 41 46 47 49 52 56 61 62 64
[24] 67 71 76 77 79 82 86 91 92 94 97

you would have to inverse a part of it, if you want to calculate 'down'

ans <- Reduce(` `, rep(c(-3, -8), 20), init = 8, accumulate = TRUE)
ans[1:(which.max(ans <= -5) - 1)]

[1]  8  5 -3

still, you would have tu 'guess' the number of repetitions needed (20 of 100 in the examples above) to create ans.

  • Related