# 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:n
#> [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()`:

```seq_len(5)
#> [1] 1 2 3 4 5

n <- 0
seq_len(n)
#> integer(0)
```

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

Categories: Coding Tutorials

Tagged as:

### jmount

Data Scientist and trainer at Win Vector LLC. One of the authors of Practical Data Science with R.

### 8 replies ›

1. Byron Dom says:

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:

seq(1,0)
[1] 1 0

seq(length.out=0)
integer(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. Glen says:

Agree that bug in the headline is misleading. Maybe replace “bug” with “situation”.

1. Thanks! That is the idea that was not coming to me. I am going to say “trap” (still strong, but less misleading).

2. Glen says:

That sounds good to me! Thanks for your articles.

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

produces-
[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 :)

1. Thank you. And sorry about that (now fixed).

And that is why I should have used RMarkdown instead of copying and pasting!

3. Turns out we are all in good company:

Brian D. Ripley: Add to package utils in R-devel, after correction. I was surprised you had fallen into the 1:0 trap.
Patrick Burns: I’m surprised too – good catch.
—Brian D. Ripley and Patrick Burns (after adding Patrick Burns’ head() to the utils package) R-devel (January 2004)