Move element from array to back of array in R

Is there an elegant way to take a vector similar to

x = c("a", "b", "c", "d", "e")

and do it

x = c("b", "c", "d", "e", "a")

I did:

x = c("a", "b", "c", "d", "e")
firstVal = x[1]
x = tail(x,-1)
x[length(x)+1] = firstVal
x
[1] "b" "c" "d" "e" "a"

It works, but is curiously ugly.

+4
source share
4 answers

Elegance is a matter of taste, and de gustibus non est dissandum:

> x <- c("a", "b", "c", "d", "e")
> c(x[-1], x[1])
[1] "b" "c" "d" "e" "a"

Does this mean that you made happy? :)

+5
source

I agreed with the answer to the taste. My personal approach:

x[c(2:length(x), 1)]
+4
source

overkill: shifter moveMe, GitHub SOfun.

:

shifter

head tail:

## Specify how many values need to be shifted
shifter(x, 1)
# [1] "b" "c" "d" "e" "a"
shifter(x, 2)
# [1] "c" "d" "e" "a" "b"

## The direction can be changed too :-)
shifter(x, -1)
# [1] "e" "a" "b" "c" "d"

moveMe

:

moveMe(x, "a last")
# [1] "b" "c" "d" "e" "a"

## Lots of options to move things around :-)
moveMe(x, "a after d; c first")
# [1] "c" "b" "d" "a" "e"
+4

head, tail, .

c(tail(x, -1), head(x, 1))

, , . , :

x <- c("a", "b", "c", "d", "e")  

gagolews <- function() c(x[-1], x[1])

senoro <- function() x[c(2:length(x), 1)]

tyler <- function() c(tail(x, -1), head(x, 1))

ananda <- function() shifter(x, 1)

user <-function(){
   firstVal = x[1]
   x = tail(x,-1)
   x[length(x)+1] = firstVal
   x
}


library(microbenchmark)
(op <- microbenchmark( 
    gagolews(),
    senoro(),
    tyler(),
    ananda(),
    user(),
times=100L))

## Unit: microseconds
##        expr    min     lq median     uq      max neval
##  gagolews()  1.400  1.867  2.333  2.799    5.132  1000
##    senoro()  1.400  1.867  2.333  2.334   10.730  1000
##     tyler() 37.320 39.187 40.120 41.519  135.287  1000
##    ananda() 39.653 41.519 42.452 43.386   69.043  1000
##      user() 24.259 25.658 26.591 27.058 1757.789  1000

enter image description here Here I expanded. I only downloaded 100 reps due to the size of the vector (1 million characters).

x <- rep(c("a", "b", "c", "d", "e"), 1000000)

## Unit: milliseconds
##        expr      min       lq   median       uq      max neval
##  gagolews() 168.9151 171.3631 179.0490 193.9604 260.5963   100
##    senoro() 192.2669 203.9596 259.1366 272.5570 341.4443   100
##     tyler() 237.4218 246.5368 303.5700 319.3999 347.3610   100
##    ananda() 237.9610 247.2097 303.9898 318.4564 342.2518   100
##      user() 225.4503 234.3431 287.8348 300.8078 319.2051   100

enter image description here

+2
source

Source: https://habr.com/ru/post/1538614/


All Articles