1

Let len = 3 denote the length of the sequence. How can I write a function that takes in len and outputs a sequence of alternating 1 and -1?

For sample, for len = 3, I want the function to return 1 -1 1. If len = 5, then 1 -1 1 -1 1, and so forth.

Adrian
  • 9,229
  • 24
  • 74
  • 132

5 Answers5

6

You can try rep with option length.out

> rep(c(1, -1), length.out = 5)
[1]  1 -1  1 -1  1

or replace

> replace(rep(1, 5), !(seq(5) %% 2), -1)
[1]  1 -1  1 -1  1

or %%

> 2 * seq(5) %% 2 - 1
[1]  1 -1  1 -1  1
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
3

An option is

f1 <- function(len) {
         s1 <- seq_len(len)
         c(-1, 1)[(s1 %%2 == 1)+1]
   }
f1(3)
#[1]  1 -1  1
f1(5)
#[1]  1 -1  1 -1  1
akrun
  • 874,273
  • 37
  • 540
  • 662
1

modulo %% and ifelse is also a possibility:

n <- 10
ifelse((1:n)%%2,1,-1)
# [1]  1 -1  1 -1  1 -1  1 -1  1 -1

However, it's not efficient:

microbenchmark::microbenchmark(
  rep(c(1, -1), length.out = n),
  c(-1, 1)[((1:n)%%2 == 1)+1],
  ifelse((1:n)%%2,1,-1))

Unit: nanoseconds
                          expr  min   lq mean median   uq   max neval
 rep(c(1, -1), length.out = n)  300  400  531    500  500  4100   100
 c(-1, 1)[((1:n)%%2 == 1) + 1] 1100 1200 1507   1300 1400 16700   100
       ifelse((1:n)%%2, 1, -1) 4100 4350 5053   4700 4950 37200   100
Waldi
  • 39,242
  • 6
  • 30
  • 78
1

An option for n > 1 could be:

rep(1, 3) * c(1, -1)

[1]  1 -1  1
tmfmnk
  • 38,881
  • 4
  • 47
  • 67
1

Quite simply:

f <- function(num,len){
  num*(-1)**(0:len)
}

> f(1,5)
[1]  1 -1  1 -1  1 -1
> f(3,5)
[1]  3 -3  3 -3  3 -3
> f(-1,5)
[1] -1  1 -1  1 -1  1

This is quite efficient at at the same time it makes sense as a numeric function. However, the most efficient one by an order of magnitude is the rep approach, specially as n get larger.

> n <- 10000
> microbenchmark::microbenchmark(
+   rep(c(1, -1), length.out = n),
+   c(-1, 1)[((1:n)%%2 == 1)+1],
+   ifelse((1:n)%%2,1,-1),
+   (-1)**(0:n)
+ )
Unit: microseconds
                          expr     min       lq      mean   median       uq      max neval
 rep(c(1, -1), length.out = n)  14.358  14.8565  15.16934  15.1425  15.3390   18.651   100
 c(-1, 1)[((1:n)%%2 == 1) + 1] 238.995 240.0120 242.85757 240.7370 241.5830  312.495   100
       ifelse((1:n)%%2, 1, -1) 311.653 314.0150 422.23417 315.2280 317.3465 5341.466   100
                    (-1)^(0:n) 211.948 212.6665 215.50381 213.2490 213.6770  339.639   100
xaviescacs
  • 309
  • 1
  • 5