Get a seq() in R with alternating steps

前端 未结 6 1216
礼貌的吻别
礼貌的吻别 2020-12-17 21:19

The seq function in R would give me a sequence from x to y with a constant step m:

seq(x, y, m)
         


        
相关标签:
6条回答
  • 2020-12-17 21:29

    Here is another idea,

    fun1 <- function(x, y, j, z){
    if(j >= y) {return(x)}else{
      s1 <- seq(x, y, j+z)
      s2 <- seq(x+j, y, j+z)
      return(sort(c(s1, s2)))
      }
    }
    
    fun1(1, 19, 2, 4)
    #[1]  1  3  7  9 13 15 19
    
    fun1(1, 40, 4, 3)
    #[1]  1  5  8 12 15 19 22 26 29 33 36 40
    
    fun1(3, 56, 7, 10)
    #[1]  3 10 20 27 37 44 54
    
    fun1(1, 2, 2, 4)
    #[1] 1
    
    0 讨论(0)
  • 2020-12-17 21:31

    You could use Reduce with accumulate = TRUE to iteratively add either 2 or 4:

    Reduce(`+`, rep(c(2,4), 10), init = 1, accumulate = TRUE)
    # [1]  1  3  7  9 13 15 19 21 25 27 31 33 37 39 43 45 49 51 55 57 61
    

    The number of times you repeat c(2,4) will determine sequence length; since it is 10 above, the sequence is length 20.

    The purrr package has an accumulate wrapper, if you prefer the syntax:

    purrr::accumulate(rep(c(2,4), 10), `+`, .init = 1)
    ## [1]  1  3  7  9 13 15 19 21 25 27 31 33 37 39 43 45 49 51 55 57 61
    
    0 讨论(0)
  • 2020-12-17 21:42

    perfect example of recycling vectors in R

    # 1. 
    x = 1; y = 19; m1 = 2; m2 = 4
    (x:y)[c(TRUE, rep(FALSE, m1-1), TRUE, rep(FALSE,m2-1))]
    # [1]  1  3  7  9 13 15 19
    # 2.
    x = 3; y = 56; m1 = 7; m2 = 10
    (x:y)[c(TRUE, rep(FALSE, m1-1), TRUE, rep(FALSE,m2-1))]
    # [1]  3 10 20 27 37 44 54
    
    0 讨论(0)
  • 2020-12-17 21:47

    Here is an alternative that uses diffinv This method over allocates the values, so as a stopping rule, I get the elements that are less than or equal to the stopping value.

    seqAlt <- function(start, stop, by1, by2) {
       out <- diffinv(rep(c(by1, by2), ceiling(stop / (by1 + by2))), xi=start)
       return(out[out <= stop])
    }
    
    seqAlt(1, 19, 2, 4)
    [1]  1  3  7  9 13 15 19
    
    0 讨论(0)
  • 2020-12-17 21:48

    First n terms of this sequence you can generate with

    x = 1; m1 = 2; m2 = 4
    
    n <- 0:10 # first 11 terms
    x + ceiling(n/2)*m1 + ceiling((n-1)/2)*m2
    # [1] 1  3  7  9 13 15 19 21 25 27 31
    
    0 讨论(0)
  • 2020-12-17 21:54

    I arrived the solution by: 1. Use cumsum with a vector c(from,rep(by,times),...), with by repeated times = ceiling((to-from)/sum(by)) times. 2. Truncate the sequence by !(seq > to).

     seq_alt <- function(from, to, by) {
       seq <- cumsum(c(from,rep(by,ceiling((to-from)/sum(by)))))
       return(seq[! seq > to])
     }
    
    0 讨论(0)
提交回复
热议问题