【发布时间】:2015-08-11 17:12:47
【问题描述】:
我正在将大量纬度/经度坐标对映射到相关的邮政编码。由于调用限制,记录数量太大而无法使用 Google Maps 或 geonames 等 API。
我有一个查找表,其中包含邮政编码和每个邮政编码的纬度/经度质心。您可以在此处获取查找表:
# zipcode data with lat/lon coordinates
url <- "http://www.boutell.com/zipcodes/zipcode.zip"
fil <- "ziplatlong.zip"
# download an unzip
if (!file.exists(fil)) { download.file(url, fil) }
unzip(fil, exdir="zips")
library(readr)
ziplkp<-read_csv("zips/zipcode.csv")
对于我数据中的每个纬度/经度对,我想通过查找该纬度/经度对与查找表中每个质心之间的最小绝对差来将其与最近的邮政编码质心匹配。
将这种“查找”函数逐行应用于大量记录的最有效方法是什么?
示例数据:经纬度坐标列表:
latlongdata <-
structure(list(dropoff_longitude = c(-73.981705, -73.993553,
-73.973305, -73.988823, -73.938484, -74.015503, -73.95472, -73.9571,
-73.971298, -73.99794), dropoff_latitude = c(40.760559, 40.756348,
40.762646, 40.777504, 40.684692, 40.709881, 40.783371, 40.776657,
40.752148, 40.720535)), row.names = c(8807218L, 9760613L, 3175671L,
10878727L, 2025038L, 5345659L, 14474481L, 1650223L, 684883L,
9129975L), class = "data.frame", .Names = c("dropoff_longitude",
"dropoff_latitude"))
print(latlongdata)
dropoff_longitude dropoff_latitude
8807218 -73.98171 40.76056
9760613 -73.99355 40.75635
3175671 -73.97330 40.76265
10878727 -73.98882 40.77750
2025038 -73.93848 40.68469
5345659 -74.01550 40.70988
14474481 -73.95472 40.78337
1650223 -73.95710 40.77666
684883 -73.97130 40.75215
9129975 -73.99794 40.72053
**ZipLooker 函数:查找从输入坐标对到最近的邮政编码质心的最小绝对距离并返回该邮政编码
library(dplyr)
ZipLooker<-function(dropoff_longitude,dropoff_latitude){
if(is.na(dropoff_longitude)|is.na(dropoff_latitude)){
z<-NA_character_
} else {
tryCatch({
x<-ziplkp1
x$latdiff=abs(dropoff_latitude-x$Latitude)
x$londiff=abs(dropoff_longitude-x$Longitude)
x$totdiff=x$latdiff+x$londiff
z<-head(top_n(x,1,-totdiff),n=1)$Postal
return(z)
}, error=function(e) NA)
}
}
使用 dplyr 的 rowwsie() 函数应用 Ziplooker 函数
latlongdata %>%
rowwise() %>%
mutate(zipcode=ZipLooker(dropoff_longitude,dropoff_latitude)
)
【问题讨论】:
-
如果你是学生,我推荐 Smarty Streets。他们为学生/学者提供免费帐户,没有通话限制。
-
谢谢,迈克尔。不是学生,现在每月 1,000 美元稍微超出预算! ;) 此外,Smarty Streets 看起来对于在给定邮政编码的情况下查找纬度/经度坐标很有用,但我正在尝试另一种方式
-
就
ZipLooker和mutate遇到的问题而言:在这种情况下,如果if没有else,如果您在你的dropoff变量之一,所以用else包裹整个TryCatch。此外,由于您最终会在此处返回一个字符变量,因此在您的if语句中使用"NA"或NA_character_会有所帮助。使用ZipLooker时不要忘记定义ziplkp参数,否则您将获得所有NA值。 -
感谢 aosmith,所有伟大的建议和更正。 ZipLooker 现在似乎可以工作了,所以我将问题改成了更具体的效率问题。