2016-03-05 44 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

是的,你是正确的谢谢。那么您是否可以编辑一下您的解决方案,以便我可以查询落在伦敦边界框中的行,如我在查询中提到的那样?万分感谢。 –

相关问题