将for循环重写为R中的-apply formular,用于georoute

时间:2017-01-14 15:54:21

标签: r lapply

我有一个大量的data.frame,包含起点和终点(纬度和经度),并且正在使用georoute包中的taRifx.geo函数,以了解有多长时间和多少时间需要从A开车到B。

数据看起来像这样(latlonlatlon_end都是characters的类:

> LL[1:10,14:15]
         latlon            latlon_end
1  52.481466 13.317647   52.518811 13.413034
2  52.518811 13.413034   52.504182 13.318051
3  52.504182 13.318051   52.502236 13.305396
4  52.502236 13.305396   52.548096 13.355104
5  52.548096 13.355104   52.569865 13.410967
6  52.569865 13.410967   52.54505 13.419071
7  52.54505 13.419071    52.527736 13.378182
8  52.527736 13.378182   52.495678 13.343019
9  52.495678 13.343019   52.496712 13.341767
10 52.496712 13.341767   52.458631 13.32529

这是我为此目的编写的for循环:

for(i in 38753:100000){
  DT[i,]=tryCatch(t(as.matrix(unlist(georoute( c(as.character(LL$latlon[i]),
                                                  as.character(LL$latlon_end[i])),
                                                verbose=TRUE, returntype=c("time", "distance"))),
                               nrow = 1, ncol = 2)),
                   error=function(a) {"."} )

}

这里的基本函数,georoute基本上给出了两个元素timedistance的列表,这就是为什么我必须先将它们取消列表,然后再将它们绑定到数据帧中。对于trycatch函数,那是为了处理georoute的偶然错误,我不知道我是怎么做的。

我真的尝试了很多方法,但只有这个似乎必须为我解决,因为不知何故这个georoute函数似乎只需要一对latlon& latlon_end一次所以我必须逐行完成。但是,如果有几十万个条目,则需要几天甚至几周的时间来处理所有这些数据。我知道我应该进入package and understand the codes behind(link inserted),所以我知道什么是更适合这个目的,但脚本太高级了我的水平,我甚至不知道脚本中我正在寻找什么确切地说。我想我可以使用lapply函数,但我无法使它工作。

任何帮助或提示或想法都会非常非常感激!

PS。更新原始georoute返回

> georoute(c(as.character(LL$latlon[1]), as.character(LL$latlon_end[1])), verbose = FALSE, returntype = c("time","distance"))
  distance time
1     9.03 1338
> georoute(c(as.character(LL$latlon[1:3]), as.character(LL$latlon_end[1:3])), verbose = FALSE, returntype = c("time","distance"))
  distance time
1   35.599 5275
> class(georoute(c(as.character(LL$latlon[1]), as.character(LL$latlon_end[1])), verbose = FALSE, returntype = c("time","distance")))
[1] "data.frame"

我认为返回的distancetime是数字的,因为它的摘要显示了4个分位数,均值,中位数等。

1 个答案:

答案 0 :(得分:0)

考虑绕过软件包并使用其数据源,即Bing Calculate a Route API,它与http://dev.virtualearth.net接口,以获取每个参数的json供稿。仔细阅读,GitHub源代码看起来很重,矢量和矩阵操作在处理过程中很重要。只需要为距离时间数据点解析json feed。

下面使用jsonlite库发送与包相同的参数来迭代地为每个Lat / Lon路由点构建URL。导入json提要后,所需的数据帧将提取到列表中。请注意:需要Bing Maps API密钥,该密钥应根据包的要求。

library(jsonlite)

BingMapsAPIkey <- "*****"

dfList <- lapply(seq(38753:100000), function(i) {

  url <- paste0("http://dev.virtualearth.net/REST/v1/Routes?wayPoint.1=", 
                gsub(" ", ",", LL$latlon[i]) , "&wayPoint.2=", gsub(" ", ",", LL$latlon_end[i]),
                "&maxSolutions=1&optimize=time&routePathOutput=Points&distanceUnit=km&travelMode=Driving",
                "&key=", BingMapsAPIkey)      
  tryCatch({
    jsondata <- fromJSON(url)
    return(jsondata$resourceSets$resources[[1]]$routeLegs[[1]]$routeSubLegs[[1]][c("travelDistance", "travelDuration")])
  }, error=function(e) return(data.frame(travelDistance=NA, travelDuration=NA)))

})

# ROW BIND DATAFRAME ELEMENTS IN LIST
geodf <- do.call(rbind, dfList)

# COLUMN BIND TO ORIGINAL DATAFRAME
df <- cbind(LL[38753:100000,], geodf)

输出 (使用上面发布的Lat / Lon数据)

#                 latlon          latlon_end travelDistance travelDuration
# 1  52.481466 13.317647 52.518811 13.413034          9.030           1338
# 2  52.518811 13.413034 52.504182 13.318051          8.148           1269
# 3  52.504182 13.318051 52.502236 13.305396          1.694            254
# 4  52.502236 13.305396 52.548096 13.355104         11.700            820
# 5  52.548096 13.355104 52.569865 13.410967          5.966            919
# 6  52.569865 13.410967  52.54505 13.419071          3.110            576
# 7   52.54505 13.419071 52.527736 13.378182          3.851            728
# 8  52.527736 13.378182 52.495678 13.343019          6.196           1051
# 9  52.495678 13.343019 52.496712 13.341767          0.986            277
# 10 52.496712 13.341767  52.458631 13.32529          6.129            947