2011-08-09 49 views
3

我在使用%進行子集化時遇到了一個奇怪的結果。關於數據集子集化的幫助

> my.data[my.data$V3 %in% seq(200,210,.01),] 
     V1  V2  V3   V4  V5  V6   V7 
56  470 48.7 209.73  yes  26.3  54  470 

這是正確的。但是當我擴大範圍...行56只是消失

> my.data[my.data$V3 %in% seq(150,210,.01),] 
     V1  V2  V3   V4  V5  V6   V7 
51  458 48.7 156.19  yes  28.2  58  458 
67  511 30.5 150.54  yes  26.1  86  511 
73  535 40.6 178.76  yes  29.5  73  535 

你能告訴我什麼是錯? 有沒有更好的方法來子集數據框?

下面是其結構

> str(my.data) 
'data.frame': 91 obs. of 7 variables: 
$ V1: Factor w/ 91 levels "100","10004",..: 1 2 3 4 5 6 7 8 9 10 ... 
$ V2: num 44.6 22.3 30.4 38.6 15.2 18.3 16.3 12.2 36.7 12.2 ... 
$ V3: num 110.83 25.03 17.17 57.23 2.18 ... 
$ V4: Factor w/ 2 levels "no","yes": 1 2 2 2 1 1 1 1 1 1 ... 
$ V5: num 22.3 30.5 24.4 25.5 4.1 28.4 7.9 5.1 24 12.2 ... 
$ V6: int 50 137 80 66 27 155 48 42 65 100 ... 
$ V7: chr "" "10004" "10005" "10012" ... 
+0

你能否澄清一下,如果你試圖返回所有行,其中'V3'在一個規定的範圍內,或者如果你想只返回等於序號的行你打算被退回? –

+0

考慮到V3四捨五入爲2個十進制數字,我認爲「V3在指定範圍內的所有行」與「等於一系列數字的行數相同,增量爲0.01」。要回答你的問題,我想第一個 – Brani

+0

'V3'可能是確切的,我不知道所有的價值。問題是'seq()'的值不是四捨五入的,確切的,那就是問題所在。無論如何,通過測試確切的平等來做事情註定會在使用浮點運算的計算機上失敗。在R中使用少於和大於運算符要安全/容易/正確得多。請參閱我的答案或@nullglob答案的第二個選項(儘管忽略了他的第一個選項,因爲這是錯誤的)。 –

回答

8

糟糕!您正試圖在不能完全代表所有數字的計算機上進行精確匹配。

> any(209.73 == seq(200,210,.01)) 
[1] TRUE 
> any(209.73 == seq(150,210,.01)) 
[1] FALSE 
> any(209.73 == zapsmall(seq(150,210,.01))) 
[1] TRUE 

的原因差異是在第二序列中,序列中的值是不準確209.73。這是用計算機進行計算時必須注意的事情。

這在interweb上的很多地方都有涉及,但是關於R,請參見R FAQ中的point 7.31

無論如何,這就是說,你正在錯誤地解決問題。你想使用適當的數字運算符:

my.data[my.data$V3 >= 150 & my.data$V3 <= 210, ] 
## or 
subset(my.data, V3 >= 150 & V3 <= 210)