2015-06-25 55 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 
相關問題