Posted on Categories Coding, TutorialsTags , ,

R Tip: Use seq_len() to Avoid The Backwards Sequence Trap

Another R tip. Use seq_len() to avoid the backwards sequence trap.

Many R users use the “colon sequence” notation to build sequences. For example:

for(i in 1:5) {
  print(paste(i, i*i))
#> [1] "1 1"
#> [1] "2 4"
#> [1] "3 9"
#> [1] "4 16"
#> [1] "5 25"

However, the colon notation can be unsafe as it does not properly handle the empty sequence case:

n <- 0

#> [1] 1 0

Notice the above example built a reversed sequence, instead of an empty sequence.

This leads to the backwards sequence trap: writing code of the form “1:length(x)” is often wrong. For example “for(i in 1:length(x)) { statements involving x[[i]] }“, which will fail for length-zero x.

To avoid this use seq_len() or seq_along():

#> [1] 1 2 3 4 5

n <- 0
#> integer(0)

integer(0)” is a length zero sequence of integers (not a sequence containing the value zero).

7 thoughts on “R Tip: Use seq_len() to Avoid The Backwards Sequence Trap”

  1. I may be missing something, but I don’t understand why you call the result of 1:0 a bug. That produces exactly what I would expect it to.

    The “:” operator can be thought of as shorthand for a call to the seq() function. This shorthand only accepts 2 of the arguments that seq() accepts—“from” and “to”—default values are used for the others. Note that seq(1,0) returns the same result that 1:0 does. To get an empty string, just issue seq(length.out=0).

    Two R results that I mentioned:

    [1] 1 0


    1. Thanks for your comment. I left a bit out which I have now put at the end of the article with an edit. Sorry about that.

      The behavior does match help(`:`), so it isn’t a bug on its own. But it is a key part of buggy for-loops such as this:


       for (i in 1:length(foo)) {
        #stuff to do the number of times that foo is long

      The above errors out if foo has length 0. And the above form is unfortunately taught a lot. The fix I suggest is use seq_len(). Yes, one can use vapply() in this case.

      I wish I had said it in the original article, but code of the form 1:length(x) is a very common (so common I forgot I had not mentioned it), and this the use of “:” and is often wrong (not what the programmer actually intended).

  2. for(i in 1:5) {
    + print(paste(i, i*i))
    + }

    [1] “1 1”
    [1] “2 4”
    [1] “3 9”
    [1] “4 16”
    [1] “5 25”

    omitting the last line makes me worry that you wrote this in python :)

Leave a Reply