为什么 `x[0]` 返回一个长度为零的向量?

15
假设我有一个向量,比如说 x <- 1:10,那么 x[0] 返回与 x 相同类型的零长度向量,即 integer(0)
我想知道这个选择背后是否有原因,而不是抛出错误或者像 x[11] 一样返回 NA。此外,如果您能够想到使用 x[0] 返回 integer(0) 有用的情况,请在回答中包含。

1
由于相同的原因,x[FALSE]不会。 - Tyler Rinker
3
乍一看,这是一个有趣的问题。 x[0] 没有被明确定义,返回值为 integer(0),而 x[11] 也没有被明确定义,返回值为 NA。此外,显式赋值 x[0] <- 5 没有返回错误或警告,但 x[0] 仍然是 integer(0) - jthetzel
@TylerRinker,我明白为什么 x[FALSE] 返回一个零长度向量了:当使用逻辑值(TRUE/FALSE)进行提取时,需要提供与 x 同等长度的向量。所以在你的例子中,FALSE 被重复使用,导致 x[rep(FALSE, length(x))],因此返回 integer(0) 是很正常的。同样的,x[TRUE] 将返回 x。但是我没有看出你将 x[0]x[FALSE] 联系起来的原因。你能否进一步解释一下呢? - flodel
1
这是基于1的索引结果,而不是零索引,但可以理解为意外情况。 - jthetzel
@Flodel 这只是一个随口说出的话(一个失败的幽默尝试)。我和你一样好奇答案是否存在。 - Tyler Rinker
2
由于无法混合使用正数和负数索引,忽略0可能是正确的答案:x [0:11] 返回 [1] 1 2 3 4 5 6 7 8 9 10 NA,而 x[-(0:5)] 返回 [1] 6 7 8 9 10。但我看不出这真的有多有用。 - Matthew Lundberg
3个回答

10

正如在 ?"[" 中所看到的:

允许使用 NA 和 0 值:包含 0 的索引矩阵行将被忽略,而包含 NA 的行会在结果中产生一个 NA。

因此,索引为 0 的情况会被忽略。我们可以从以下示例中看到这一点。

x <- 1:10
x[c(1, 3, 0, 5, 0)]
#[1] 1 3 5

如果我们给它的唯一索引是0,那么适当的响应是返回一个空向量。


谢谢@Dason。我认为值得注意的是,你引用的这句话是“矩阵和数组”部分的一部分,而不是“原子向量”,因此它没有明确记录或回答我的问题,但也许可以用于推断。 - flodel
1
无论如何,虽然它可以帮助讨论,但我对“因为文档这样说”这样的答案不是很感兴趣;我更关心为什么做出了这个特定的选择。其他一些答案和评论提供了一些合理的解释,说明为什么它不应该像x[11]那样返回NA。所以我想知道为什么开发人员没有选择抛出错误。 - flodel
出现错误是不好的,因为在像拆分这样的情况下,您希望它返回某些内容而不是错误。 :) 我仍然在推动我编造的听起来合理的想法。 - Tyler Rinker
1
@Dason,你我都知道我不知道那个。 - Tyler Rinker
@flodel - 我同意你的观点,这也是我问Tyler是否知道它是否使用0索引的原因,因为我认为幕后发生的事情可能更接近于你所描述的。我希望我能给你一个更好的答案,而不仅仅是“文档规定了这样做”,因为这是一个有趣的问题,听到核心开发人员的理由会很好。可能只是因为他们最初这样做,并没有太多考虑,现在出于兼容性的原因而保持这种方式。但可能有更好的理由... - Dason
显示剩余4条评论

2

由于数组索引从1开始,因此索引0没有意义。该值将被忽略作为向量索引。


2
作为一个非程序员,我尝试翻译以下内容。我认为可能是因为你需要一种占位符来表明这里发生了某些事情但没有返回任何内容。使用类似于 tables 和 split 这样的东西,这变得更加明显。例如,当您制作值表并说有零个该单元格时,您需要保持该由向量中的字符串制成的单元格没有任何值。 x [0] == 0 不适用,因为它不是零的数值,而是没有任何值。
因此,在以下拆分中,我们需要一个占位符,integer(0) 代表未返回任何值的占位符,它与 0 不同。请注意,对于第二个占位符,它返回的是 numeric(0),表示它是数字占位符。
with(mtcars, split(as.integer(gear), list(cyl, am, carb)))
with(mtcars, split(gear, list(cyl, am, carb)))

从某种意义上说,我的x[FALSE]反驳是正确的,因为它占据了向量中不存在的零位置。

好吧,我刚才说的这个balonga是正确的,直到有人争辩并推翻它为止。

PS:本指南第19页(链接)指出,integer()和integer(0)是空整数。

相关SO帖子:如何捕获integer(0)?


1
我仍然觉得这并没有回答为什么它不像x [11]一样返回NA的问题。 - Dason
1
因为 x[11] 存在,只是缺失了。尝试 x[15] <- 3;x,你会发现在向量中每个整数值都存在,除了0。即使 x[Inf] 存在,它也是缺失的 (NA),而 x[0] 永远不存在。把 x[n] 看作位置,这就有意义了。没有 x[0] 位置这种东西。 - Tyler Rinker
@TylerRinker:我同意你的观点,但为了进一步讨论,如果x[0]不存在,为什么x[0] <- 1不会返回警告或错误?我们难道不应该期望它返回类似于invalid first argument这样的内容吗?这是assign(x[0], 1)返回的错误信息。 - jthetzel
1
@jthetzel 这并不是一个好的例子,因为 assign(x[1], 1) 同样会产生无效的第一个参数。但是,assign("x[1]", 1)assign("x[0]", 1) 都能够成功执行。 - Dason
@TylerRinker 我发现关于赋值语句的问题是在发布后不久,但由于已经超过了五分钟,我无法修改我的评论。不过,我不明白为什么你会期望那个identical语句出错。 - Dason
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接