2016-03-05 79 views
0

我正在加載可用於stanford存儲庫的R中的Gowalla數據集並重命名列名稱。 https://snap.stanford.edu/data/loc-gowalla.html當在包含緯度的列中搜索時,R返回null

Gowalla<-read.csv(file = "Gowalla_edges.txt", sep="\t", header=FALSE) 
colnames(Gowalla)<-c("uid", "utc", "lat", "long", "vid") 

我的目標是選擇含LODON全市範圍內的經度和緯度的行。根據緯度和經度給出的邊界框在 http://www.mapdevelopers.com/geocode_bounding_box.php

您可以訪問和搜索倫敦的邊界框,它給出了緯度和經度的範圍。

現在,當我在R代表一個特定的緯度搜索例如

which(Gowalla$lat == 30.23591) 

說,因爲它是在數據中的第一個緯度,則返回null哪裏!

但是如果我搜索VID是一個整數,而不是像緯度

which(Gowalla$vid==22847) 

小數它給我的行號的那個值。

所以我的問題是爲什麼我不能使用「which」函數來搜索緯度和經度,爲什麼gowalla在我的情況下返回null?

一旦我找到答案,我可以使用if-else並搜索落在我倫敦邊界框中的行。是否有任何有效的方法來搜索落在倫敦邊界框中的行?

倫敦邊框是 緯度51.672343和51.384940和經度 經度0.148271 -0.351468

謝謝之間。

+2

不應使用'=='來搜索浮點值。您應該使用'這(ABS(Gowalla的$ LAT - 30.23591)<= 0.00000001)''那裏是0.00000001'您所需的寬容 – digEmAll

+2

這是不是一個好主意來比較浮點數與''==。改用'all.equal()'。欲瞭解更多信息,請參閱此[所有時間經典SO問題](http://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal)。 – RHertel

+1

當'R'打印數字值時,它將它們四捨五入。所以'30.23591'不是實際的值,而是一個圓整的版本。如果你嘗試'哪個(Gowalla $ lat == Gowalla $ lat [1])',你會收到一個不空的結果。要選擇框內的數據,請嘗試使用'lat <51.672343&lat> 51.384940&lon <0.148271&lon> -0.351468'(我省略了'Gowalla $'部分)。 – nicola

回答

4

嘗試搜索使用索引

which(sapply(Gowalla$lat, all.equal,30.23591)==TRUE) 

正如answers to this question解釋,浮點算術的缺陷可能會導致直觀的結果。功能all.equal()專爲捕獲這些情況而定製。如果在計算精度範圍內滿足等式,則返回TRUE。但是,由於它在數字本質上不相等的情況下以相當冗長的方式返回差異,因此我們需要明確檢查它的輸出是否等於TRUE,以僅過濾滿足此斷言的結果。


正如@digEmAll指出,另一種方法,這似乎是在這種情況下比較有前途,包括引入用戶定義的誤差或公差,如:

tol <- 1.e-4 

然後我們就可以檢查我們正在尋找的值是否是該保證金誤差範圍內使用

which(abs(Gowalla$lat - 30.23591) < tol) 

我們需要的功能abs()這裏,因爲各色的的大小這很重要,而不是它的標誌。選擇較大的tol時,可能選擇的值越多。


在倫敦的例子在OP的端部所提到的,一個可能使用兩個不同的tol值,一個用於lonlat

tol_lat <- 1.01 * (51.672343 - 51.384940)/2 # half of the latitude range of region of interest, plus 1% 
tol_lon <- 1.01 * (0.148271 + 0.351468)/2 # same for longitudinal values 

和限定中央值作爲

lat_c <- (51.672343 + 51.384940)/2 
lon_c <- (0.148271 - 0.351468) /2 

最後,可以檢查數據幀中的值與

which(abs(Gowalla$lat - lat_c) < tol_lat & abs(Gowalla$long - lon_c) < tol_lon) 

最後注意到,數字的在R標準表示包括7位,其可以是接近或超出了被測試什麼限制。因此,它可以是在腳本的開始時就確定

options(digits=19) 

有用,特別是如果tol被選擇爲小,接近或低於1e-7


感謝@nicola指出了此答案以前版本中的錯誤。

+0

感謝您的解釋是可悲的是真的,你可以比較小的值保存到整數。除了在代碼中缺少一個錯字''),我試了一下,它給了我'整數(0)'!所以爲了避免複雜性,我可以用'1000000'乘以所有的lats和long行,並將所有的數據轉換爲整數,然後在執行計算後,我可以再次劃分並得到我的lats和longs?這將是一個很少的頭痛! –

+1

我檢查了你的文件,第一項的緯度值是'30.2359091167'。所以這個數字和'30.23591'之間有很大區別,在這種情況下'all.equal()'不會返回'TRUE'是正常的。你可以嘗試使用'options(digits = 19)'來更詳細地顯示數字;或使用@digEmAll描述的方法 - 引入個人準確度閾值。 – RHertel

+0

是的,你是正確的謝謝。那麼您是否可以編輯一下您的解決方案,以便我可以查詢落在倫敦邊界框中的行,如我在查詢中提到的那樣?萬分感謝。 –

相關問題