Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular shift of vector (equivalent to numpy.roll)

Tags:

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 there a function like that in R? I've been googling around, but "R Roll" mostly gives me pages about Spanish pronunciation.

like image 217
sudo make install Avatar asked Sep 13 '13 16:09

sudo make install


People also ask

How do you shift a circle in Python?

Using Collection deque This method allows us to shift by n elements ahead at once, using both directions, forward and backward. We just need to use the rotate method on the deque object. Note, that you can easily convert a deque object to a list like list(x) where x is a deque object.

How do you shift elements in a Numpy array?

To shift the bits of integer array elements to the right, use the numpy. right_shift() method in Python Numpy. Bits are shifted to the right x2. Because the internal representation of numbers is in binary format, this operation is equivalent to dividing x1 by 2**x2.

How do you move a value in an array in Python?

Shift Array in Python Using the numpy.roll(array, shift, axis) method takes the array as input and rotates it to the positions equal to the shift value. If the array is a two-dimensional array, we will need to specify on which axis we need to apply the rotation; otherwise, the numpy.


2 Answers

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 
like image 57
Simon O'Hanlon Avatar answered Sep 19 '22 14:09

Simon O'Hanlon


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 
like image 28
Josh O'Brien Avatar answered Sep 19 '22 14:09

Josh O'Brien