我在数据帧中有两个点的经度和经度。我在R中使用下面的代码来获得行驶距离。
library(XML)
library(RCurl)
latlon2ft <- function(origin,destination){
xml.url <- paste0('http://maps.googleapis.com/maps/api/distancematrix/xml?origins=',origin,'&destinations=',destination,'&mode=driving&sensor=false')
xmlfile <- xmlParse(getURL(xml.url))
dist <- xmlValue(xmlChildren(xpathApply(xmlfile,"//distance")[[1]])$value)
distance <- as.numeric(sub(" km","",dist))
ft <- distance*3.28084 # FROM METER TO FEET
return(ft)
}
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")
distance <- list()
for(i in 1:nrow(test)){
dat <- latlon2ft(test[i,'origin1'],test[i,'destination1'])
distance[[i]] <- dat
}
all_distance <- do.call("rbind", distance)
但是我收到了以下错误。
Error in xpathApply(xmlfile, "//distance")[[1]] : subscript out of bounds
3 xmlChildren(xpathApply(xmlfile, "//distance")[[1]])
2 xmlValue(xmlChildren(xpathApply(xmlfile, "//distance")[[1]])$value)
1 latlon2ft(test[i, "origin1"], test[i, "destination1"])
这是我的数据样本:
store_lat | store_lng | lat | lng
19.21368 | 72.99034 | 19.1901094 | 72.9758546
19.10749 | 72.86444 | 19.1052534 | 72.8609213
19.01480 | 72.84545 | 18.9942502 | 72.8365256
19.01480 | 72.84545 | 19.1453449 | 72.8367015
我的代码中哪里错了?据我所知,我无法在运行循环时将值正确传递给函数。但我无法找到解决方法。提前感谢您的帮助。
答案 0 :(得分:2)
出现了下标超出范围错误,因为您没有为URL使用正确的API格式。它会从Google服务器生成xmlfile
响应:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address/>
<destination_address/>
<row>
<element>
<status>NOT_FOUND</status>
</element>
</row>
</DistanceMatrixResponse>
其中没有有效的distance
。
错误是网址中origins
和destinations
周围的单引号。当您将它们与代码
test$origin1 = paste0("'",test$store_lat,",",test$store_lng,"'")
test$destination1 = paste0("'",test$lat,",",test$lng,"'")
您在值周围添加'
个单引号,这是不正确的。如果你删掉单引号:
test$origin1 = paste0(test$store_lat,",",test$store_lng)
test$destination1 = paste0(test$lat,",",test$lng)
然后,您的代码会生成http://maps.googleapis.com/maps/api/distancematrix/xml?origins=19.21368,72.99034&destinations=19.1901094,72.9758546&mode=driving&sensor=false"
的正确网址,而不会使用单引号。然后,Google服务器返回的结果XML为:
<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
<status>OK</status>
<origin_address>External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India</origin_address>
<destination_address>A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India</destination_address>
<row>
<element>
<status>OK</status>
<duration>
<value>981</value>
<text>16 mins</text>
</duration>
<distance>
<value>4908</value>
<text>4.9 km</text>
</distance>
</element>
</row>
</DistanceMatrixResponse>
现在有一个有效的距离值。
详细信息的更多详细信息答案 1 :(得分:1)
我写了googleway
包,可以为你做很多艰苦的工作。
如果您拥有有效的Google API密钥,则可以使用函数google_distance()
获取多个位置之间的距离矩阵。
library(googleway)
key <- "your_api_key"
## distances for individual locations
google_distance(origins = list(c(df[1, "store_lat"], df[1,"store_lng"])),
destinations = list(c(df[1, "lat"], df[1, "lng"])),
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
#
# $rows
# elements
# 1 4.9 km, 4874, 17 mins, 995, 15 mins, 904, OK
#
# $status
# [1] "OK"
## distance matrix for multiple locations
origins <- split(df[, c("store_lat","store_lng")], f = row.names(df))
origins <- lapply(origins, as.numeric)
destinations <- split(df[, c("lat","lng")], f = row.names(df))
destinations <- lapply(destinations, as.numeric)
google_distance(origins = origins,
destinations = destinations,
key = key)
# $destination_addresses
# [1] "A-5, Chhatraprati Sambhaji Rd, Ghantali, Thane West, Thane, Maharashtra 400602, India"
# [2] "A-102, Sahar Rd, Bramhan Wadi, Andheri East, Mumbai, Maharashtra 400047, India"
# [3] "Lalbaug Flyover, Ghodapdeo, Ganesh Gully, Parel, Mumbai, Maharashtra 400012, India"
# [4] "24-A/101, Behram Baug, Jogeshwari West, Mumbai, Maharashtra 400047, India"
#
# $origin_addresses
# [1] "External Bypass Rd, Laxmi Nagar, Balkum Pada, Majiwada, Thane, Maharashtra 400608, India"
# [2] "Cardinal Gracias Rd, Kanti Nagar, J B Nagar, Andheri East, Mumbai, Maharashtra 400059, India"
# [3] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
# [4] "Dadar TT Flyover, Lokmanya Tilak Colony, Dadar, Mumbai, Maharashtra 400014, India"
#
# $rows
# elements
# 1 4.9 km, 26.1 km, 33.2 km, 28.2 km, 4874, 26130, 33150, 28194, 17 mins, 49 mins, 45 mins, 56 mins, 995, 2931, 2697, 3384, 16 mins, 44 mins, 41 mins, 48 mins, 943, 2638, 2471, 2906, OK, OK, OK, OK
# 2 20.3 km, 0.9 km, 16.0 km, 9.1 km, 20303, 872, 16045, 9140, 44 mins, 4 mins, 34 mins, 25 mins, 2655, 257, 2055, 1512, 39 mins, 4 mins, 32 mins, 21 mins, 2364, 214, 1938, 1231, OK, OK, OK, OK
# 3 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
# 4 25.6 km, 13.7 km, 4.5 km, 20.6 km, 25591, 13697, 4545, 20616, 39 mins, 27 mins, 8 mins, 38 mins, 2317, 1604, 500, 2297, 34 mins, 22 mins, 6 mins, 32 mins, 2033, 1319, 387, 1907, OK, OK, OK, OK
#
# $status
# [1] "OK"
答案 2 :(得分:0)
test$origin1 = paste0(test$store_lat, ",", test$store_lng)
test$destination1 = paste0(test$lat, ",", test$lng)
distance <- list()
for(i in 1:nrow(test)) {
dat <- latlon2ft(test[i, 'origin1'], test[i, 'destination1'])
distance[[i]] <- dat
}
没有“'”