2015-06-25 29 views
0

在使用范围引用中,当'['']'中的操作与父对象的尺寸不匹配时,通常希望看到错误或至少有警告消息,不过,我刚刚发现,我没有看到所述的警告和错误。有没有这样的设置或强制错误的方法?例如:引用不同尺寸的R范围不会导致错误

x = 1:5 
y = 10:12 
x[y>10] 
y[x>2] 

同样这也适用于数据帧和其它的R对象:

dat = data.frame(x=runif(100),y=1:100) 
dat[sample(c(TRUE,FALSE),23),c(TRUE,FALSE)] 

参考文献的无声重复和截短,以匹配父对象的尺寸是出乎意料的,具有使用R表示多年来,我从未注意过这一点。我正在使用Windows的R Console(64位)3.0.1(可以更新是的,但我希望这不是原因)。

编辑:修正data.frame作为data.frame的示例,不允许使用比列更多的列引用。谢谢zero323。

+2

随着一段代码您提供我得到简单的'错误...未定义的列选择“。 – zero323

+0

不,子集不检查长度是否匹配。如果是这样的话,那么在很多情况下,像“x [c(TRUE,FALSE)]”这样的再循环就可以采取其他任何价值。或者,对于这个问题,'x [TRUE]'可以获取每个值 - 这可能会以编程方式有用。 – thelatemail

+0

@thelatemail关于回收的意图,我肯定同意'x [TRUE]'的情况,并且我看到了回收长度为(x)的除数的情况。对于非倍数的截断情况和回收,我希望对大多数用户来说通常是一种无意的行为,并且至少应该抛出警告。 @josilber用他的解决方案涵盖了这些案例。干杯。 – SuaveIncompetence

回答

2

您可以修改`[.data.frame`函数抛出与逻辑矢量索引时的警告不平均分配的行数:

`[.data.frame` <- function(x, i, j, drop = if (missing(i)) TRUE else length(cols) == 1) { 
    if (!missing(i) && is.logical(i) && nrow(x) %% length(i) != 0) { 
    warning("Indexing data frame with logical vector that doesn't evenly divide row count") 
    } 
    base::`[.data.frame`(x, i, j, drop) 
} 

下面是用150行虹膜数据集示范,传递长度11(应该引起预警)和15的逻辑索引向量(应该不会导致警告):

iris[c(rep(FALSE, 10), TRUE),] 
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
# 11   5.4   3.7   1.5   0.2  setosa 
# 22   5.1   3.7   1.5   0.4  setosa 
# 33   5.2   4.1   1.5   0.1  setosa 
# 44   5.0   3.5   1.6   0.6  setosa 
# 55   6.5   2.8   4.6   1.5 versicolor 
# 66   6.7   3.1   4.4   1.4 versicolor 
# 77   6.8   2.8   4.8   1.4 versicolor 
# 88   6.3   2.3   4.4   1.3 versicolor 
# 99   5.1   2.5   3.0   1.1 versicolor 
# 110   7.2   3.6   6.1   2.5 virginica 
# 121   6.9   3.2   5.7   2.3 virginica 
# 132   7.9   3.8   6.4   2.0 virginica 
# 143   5.8   2.7   5.1   1.9 virginica 
# Warning message: 
# In `[.data.frame`(iris, c(rep(FALSE, 10), TRUE),) : 
# Indexing data frame with logical vector that doesn't evenly divide number of rows 

iris[c(rep(FALSE, 14), TRUE),] 
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
# 15   5.8   4.0   1.2   0.2  setosa 
# 30   4.7   3.2   1.6   0.2  setosa 
# 45   5.1   3.8   1.9   0.4  setosa 
# 60   5.2   2.7   3.9   1.4 versicolor 
# 75   6.4   2.9   4.3   1.3 versicolor 
# 90   5.5   2.5   4.0   1.3 versicolor 
# 105   6.5   3.0   5.8   2.2 virginica 
# 120   6.0   2.2   5.0   1.5 virginica 
# 135   6.1   2.6   5.6   1.4 virginica 
# 150   5.9   3.0   5.1   1.8 virginica 
+0

是的,这是有道理的,我猜测它的意思是长度(j)不是长度(cols)。否则,它似乎按预期工作,我正在考虑这样的事情,但我从来没有游戏覆盖任何内置的情况,以防万一我不允许某些情况下,你的答案似乎。 – SuaveIncompetence

0

扩展在@josilber我已经写了的情况下,任何人都希望它的原子向量和矩阵子集如下:

`[` <- function(x, i) { 
if(!missin 

g(i) && is.logical(i) && (length(x) %% length(i) != 0 || length(i) > length(x))) { 
     warning("Indexing atomic vector with logical vector that doesn't evenly divide row count") 
    } 
    base::`[`(x,i) 
} 

`[` <- function(x,i,j,...,drop=TRUE) { 
    if (!missing(i) && is.logical(i) && nrow(x) %% length(i) != 0) { 
     warning("Indexing matrix with logical vector that doesn't evenly divide row count") 
    } 
    if (!missing(j) && is.logical(j) && nrow(x) %% length(j) != 0) { 
     warning("Indexing matrix with logical vector that doesn't evenly divide column count") 
    } 
    base::`[`(x,i,j,...,drop) 
} 

测试我原来的例子之后与此修改,现可生产预警等操作的行为按正常:

> x = 
1:5 
> y = 10:12 
> x[y>10] 
[1] 2 3 5 
Warning message: 
In x[y > 10] : 
    Indexing atomic vector with logical vector that doesn't evenly divide row count 
> y[x>2] 
[1] 12 NA NA 
Warning message: 
In y[x > 2] : 
    Indexing atomic vector with logical vector that doesn't evenly divide row count 
> x[x>2] 
[1] 3 4 5 
> x[1:2] 
[1] 1 2 
相关问题