R中基于零的数组/向量

Ajo*_*joy 5 indexing r

是否有某种方法可以使R对向量和其他序列数据结构使用从零开始的索引,如下所述,例如在C和python中。

我们有一些代码可以在C中进行一些数值处理,我们正在考虑将其移植到R中以利用其先进的统计功能,但是(根据我对谷歌搜索后的理解)缺少基于零的索引使这项工作有些困难更加困难。

ins*_*ven 6

我想展开辛寅的回答。可以定义新的类(如zero-based_vector)、[该类的方法,然后将该类分配给目标向量的属性。

# 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"
Run Code Online (Sandbox Code Playgroud)

顺便说一句,没有任何东西会被破坏,因为我们不会覆盖.Primitive('[')


Xin*_*Yin 5

TL; DR:只是不要这样做!

我认为从零/一开始的索引并不是将C代码移植到R的主要障碍。但是,如果您确实认为有必要这样做,则可以覆盖.Primitive('[')函数,从而更改C的行为。 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
Run Code Online (Sandbox Code Playgroud)

但是,这可能非常危险,因为您更改了基本索引行为,并且可能对所有利用子集和索引的库和函数造成意外的级联效果。

例如,由于子集和索引可以接受其他类型的数据作为选择器(例如布尔矢量),并且简单的覆盖函数没有考虑到这一点,因此您可能会遇到非常奇怪的行为:

> 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
Run Code Online (Sandbox Code Playgroud)

尽管可以通过修改覆盖功能解决此问题,但是您仍然可能遇到其他问题。

另一个例子:

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

您永远都不知道哪里可能出问题了。所以,别这样。