Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zero based arrays/vectors in R

Tags:

indexing

r

Is there some way to make R use zero based indexing for vectors and other sequence data structures as is followed, for example in C and python.

We have some code that does some numerical processing in C, we are thinking of porting it over into R to make use of its advanced statistical functions, but the lack(as per my understanding after googling) of zero based index makes the task a bit more difficult.

like image 479
Ajoy Avatar asked Aug 14 '14 11:08

Ajoy


2 Answers

TL;DR: just don't do it!

I don't think the zero/one-based indexing is a major obstacle in porting your C code to R. However, if you truly believe that it is necessary to do so, you can certainly override the .Primitive('[') function, changing the behavior of the indexing/subsetting in R.

# rename the original `[`
> index1 <- .Primitive('[')

# WICKED!: override `[`. 
> `[` <- function(v, i) index1(v, i+1)
> x <- 1:5
> x[0]
[1] 1
> x[1]
[1] 2
> x[0:2]
[1] 1 2 3

However, this can be seriously dangerous because you changed the fundamental indexing behavior and can cause unexpected cascading effects for all libraries and functions that utilizes subsetting and indexing.

For example, because subsetting and indexing can accept other type of data as a selector (boolean vector, say), and the simple overriding function doesn't take that into account, you can have very strange behavior:

> x[x > 2] # x > 2 returns a boolean vector, and by + 1, you convert 
           # boolean FALSE/TRUE to numeric 0/1
[1] 1 1 2 2 2

Although this can be addressed by modifying the overriding function, you still may have other issues.

Another example:

> (idx <- which(x > 2)) # which() still gives you 1-based index
> x[idx]
[1]  4  5 NA

You never know where things might go wrong horribly. So, just don't.

like image 189
Xin Yin Avatar answered Nov 14 '22 22:11

Xin Yin


I want to develop Xin Yin's answer. It's possible to define new class (like zero-based_vector), method [ for this class and then assign this class to attributes of target vectors.

# define new method for our custom class 
index1 <- .Primitive('[')
`[.zero-based_vector` <- function(v, i) index1(as.vector(v), i+1)

x <- letters
# make `x` a zero-bazed_vector 
class(x) <- c("zero-based_vector", class(x))
# it works!
x[0:3]
# [1] "a" "b" "c" "d"

By the way, nothing will be broken, because we don't override .Primitive('[')

like image 37
inscaven Avatar answered Nov 14 '22 21:11

inscaven