R对矢量不一致行为

时间:2017-05-17 14:11:08

标签: r

如果符合条件,请考虑从匹配特定集合的向量中删除这些元素。预期的行为是删除匹配的行为,特别是如果没有匹配则删除none:

> d = 1:20
> d
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
> d[-which(d > 10)]
 [1]  1  2  3  4  5  6  7  8  9 10
> d[-which(d > 100)]
integer(0)

我们在这里看到,最终声明既做了一些非常意外的事情,也默默地隐藏了错误,甚至没有警告。

我最初认为这是选择空索引选择向量的所有元素的不良(但一致)结果

http://stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html

通常用于例如通过写

选择矩阵的第一列m
m[ , 1]

然而,这里观察到的行为与将空矢量解释为"没有元素",而不是"所有元素":

一致
> a = integer(0)

选择"没有元素"完全按预期工作:

> v[a]
numeric(0)
然而,删除"没有元素"没有:

> v[-a]
numeric(0)

对于空矢量,既不选择元素也不删除所有元素都需要不一致。

显然可以通过检查which()返回非零长度或使用此处涵盖的逻辑表达式来解决此问题In R, why does deleting rows or cols by empty index results in empty data ? Or, what's the 'right' way to delete?

但我的两个问题是:

  1. 为什么行为不一致?
  2. 为什么默默在没有错误或警告的情况下做错了?

1 个答案:

答案 0 :(得分:4)

这不起作用,因为which(d > 100)-which(d > 100)是同一个对象:空向量与该空向量的负数之间没有区别。

例如,想象一下:

d = 1:10

indexer = which(d > 100)
negative_indexer = -indexer

这两个变量是相同的(这是唯一一致的行为 - 转动空向量的所有元素为负,因为它没有元素,所以它是相同的。)

indexer
#> integer(0)
negative_indexer
#> integer(0)
identical(indexer, negative_indexer)
#> [1] TRUE

此时,您不能指望d[indexer]d[negative_indexer]提供不同的结果。也没有提供错误或警告的地方:它不知道什么时候传递一个空的向量,你“意味着”那个空向量的负面版本。

解决方案是,对于子集,您根本不需要which():您可以使用d[d > 10]而不是原始示例。因此,您可以使用!(d > 100)d <= 100作为否定索引。这符合您的预期,因为d > 10!(d > 100)是逻辑向量而不是索引向量。