Take the 2-minute tour ×

What is the reason that vector indices in R start with 1, instead of the usual 0?


> arr<-c(10,20)
> arr[0]
> arr[1]
[1] 10
> arr[2]
[1] 20

Is it just that they want to store extra information about the vector and didn't know where to store it except as the vector's first element?

share|improve this question

closed as primarily opinion-based by Ben Bolker, Eat Å Peach, Roland, Thomas, Don Roby Dec 15 '13 at 17:35


"Usual 0" is somewhat relative. My first cup of coffee in the morning is my first, not my zero-th. –  Dirk Eddelbuettel Jun 28 '10 at 19:05
But when you're born you're zero years old and have to wait a year for your first birthday. –  Frank Jun 28 '10 at 19:07
Because age is measured in completed years. Just a different convention. My fingers are still numbered 1 to 10. –  Dirk Eddelbuettel Jun 28 '10 at 19:10
@Dirk: As I was slurping down my fifth cup of coffee today, I was asking myself the same question: was it really my fourth? Did my first cup even count? –  Shane Jun 28 '10 at 19:12
So do Fortran, ALGOL, MATLAB, COBOL, Smalltalk and others... See en.wikipedia.org/wiki/… –  nico Jun 28 '10 at 19:33

7 Answers 7

FORTRAN is one language that starts arrays at 1. Mathematicians deal with vectors that always start with component 1 and go through N. Linear algebra conventions start with row and column numbered 1 and go through N as well.

C started with zero because of the pointer arithmetic that was implicit underneath. Java, JavaScript, C++, and C# followed suit from C.

share|improve this answer
Exactly. C's 0 indexing always seemed utterly reasonless to me until I learned a little bit about pointer arithmetic. Then it made sense as a design choice. –  Sharpie Jul 1 '10 at 2:16
@Sharpie, can you explain that comment? I know a bit about pointers but do not follow you. –  gwg Feb 6 at 15:07

Vectors in math are often represented as n-tuples, elements of which are indexed from 1 to n. I suspect that r wanted to stay true to this notation.

share|improve this answer

0 is only "usual" because that's what C did, and a lot of later languages slavishly copied C syntax. By default in Fortran arrays are 1-based.

In Ada there is no default and you have to pick the beginnning and end ranges. Interestingly, it seems that most code I've come across picks '1' for the lower bound. I think that's a pretty good indication of where folks would have gone given a free choice.

share|improve this answer

Frank, I think you were misinterpreting what you saw when you typed arr[0]. The numeric(0) just means that the result is a numeric vector with no elements. It does not mean that the type of the vector is being "stored" in element 0. You would have gotten the same result if you had typed, for example, arr[arr > 30]. No element meets that condition, so the result vector has no elements. Likewise, no element has index 0. This is intentional, and has nothing to do with the 0 space being used for something else.

share|improve this answer
I think that is what Dirk try to explain but you got the point. +1 –  Marek Jun 30 '10 at 8:23

R is a "platform for experimentation and research". Its aim is to enable "statisticians to use the full capabilities of such an environment" without rethinking the way they usually deal with statistics. So people use formulas to make regression models, and people start counting at 1.

share|improve this answer

Actually, I think that the C like version that "start with 0" is very logical when you look at the way the memory is organized. In C we can write the following :

int* T = new int[10];

The first element of the array is *T. This is perfectly "logical" because *T is the adress of the first memory case pointed. The second element is the second case so *(T+1) : we move forward by one "sizeof(int)".

To make the code more readable, C implemented an alias : T[i] for *(T+i). To access the first element, you have to access *T that is T[0]. That's perfectly natural.

This idea is extended by iterators :

std::vector<int> T(10);
int val = *(T.begin()+3);

T[i] is just an alias for *(T.begin()+i).

In fortran/R, we usually start with 1 because of mathematical issues but there's certainly other good choices (cf this link for example). Do not forget that fortran can easily use array that start with 0 :

REAL T(0:9)
T(0) = 3.14
share|improve this answer

You're doing it wrong. If you want to store additional attributes in an object, use attr:

> foo <- 1:20
> attr(foo, "created") <- Sys.time()               # just as an example
> str(foo)
 atomic [1:20] 1 2 3 4 5 6 7 8 9 10 ...
 - attr(*, "created")= POSIXct[1:1], format: "2010-06-28 14:07:15"    # our time
> summary(foo)                                     # object works as usual
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    5.75   10.50   10.50   15.20   20.00 
share|improve this answer
What am I doing wrong? I wasn't trying to store any additional information in my object. –  Frank Jun 28 '10 at 19:11
I misread the last line of your question. To answer your question: R isn't C. That's all. –  Dirk Eddelbuettel Jun 28 '10 at 19:30
