Circular shift of vector (equivalent to numpy.roll)

后端 未结 4 1277
悲&欢浪女
悲&欢浪女 2020-11-28 15:25

I have a vector:

a <- c(1,2,3,4,5)

And I\'d like to do something like:

b <- roll(a, 2) # 4,5,1,2,3

Is t

相关标签:
4条回答
  • 2020-11-28 15:26

    The package binhf has the function shift:

    library(binhf)
    
    shift(1:5, places = 2)
    #[1] 4 5 1 2 3
    

    places can be positive or negative

    0 讨论(0)
  • 2020-11-28 15:28

    You can also use the permute package:

    require(permute)
    
    a <- c(1,2,3,4,5)
    
    shuffleSeries(a, start = 2)
    

    output:

    [1] 3 4 5 1 2
    
    0 讨论(0)
  • 2020-11-28 15:32

    How about using head and tail...

    roll <- function( x , n ){
      if( n == 0 )
        return( x )
      c( tail(x,n) , head(x,-n) )
    }
    
    roll(1:5,2)
    #[1] 4 5 1 2 3
    
    #  For the situation where you supply 0 [ this would be kinda silly! :) ]
    roll(1:5,0)
    #[1] 1 2 3 4 5
    

    One cool thing about using head and tail... you get a reverse roll with negative n, e.g.

    roll(1:5,-2)
    [1] 3 4 5 1 2
    
    0 讨论(0)
  • 2020-11-28 15:47

    Here's an alternative which has the advantage of working even when x is "rolled" by more than one full cycle (i.e. when abs(n) > length(x)):

    roll <- function(x, n) {
        x[(seq_along(x) - (n+1)) %% length(x) + 1]
    }
    
    roll(1:5, 2)
    # [1] 4 5 1 2 3
    roll(1:5, 0)
    # [1] 1 2 3 4 5
    roll(1:5, 11)
    # [1] 5 1 2 3 4
    

    FWIW (and not that it's worth much) it also works on data.frames:

    head(mtcars, 1)
    #           mpg cyl disp  hp drat   wt  qsec vs am gear carb
    # Mazda RX4  21   6  160 110  3.9 2.62 16.46  0  1    4    4
    head(roll(mtcars, 2), 1)
    #           gear carb mpg cyl disp  hp drat   wt  qsec vs am
    # Mazda RX4    4    4  21   6  160 110  3.9 2.62 16.46  0  1
    
    0 讨论(0)
提交回复
热议问题