Ggmap mapdist function repeats computation for specific OD pairs
I want to find distance and travel time using mapdist function in ggmap. This function works well for most Lat / Long primary target pairs. However, for some ODs, the result is repeated.
In this example, the repetition occurs for the 8th and 12th OD pair. As a result, there are 14 lines of data in the output, although the input has only 12 lines.
Any suggestions?
O <- c("37.8405983 -122.2544365",
"37.7589152 -122.4062322",
"37.7517621 -122.4062364",
"37.9659228 -122.505765",
"37.6969336 -121.8650777",
"37.9457334 -122.3152847",
"38.1237134 -122.23956",
"37.8911093 -122.2813663",
"37.9067555 -122.0145836",
"38.0673887 -122.2185562",
"37.7807761 -122.2102385",
"37.8911093 -122.2813663")
D <- c("37.8454493 -122.2833803",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625")
DF <- cbind(O, D); DF <- as.data.frame(DF)
GMAPDist <- mapdist(from = O, to = D, mode = "driving",output = "simple")
However, if I call the function on only one OD pair, then the output is as expected. See below:
mapdist(from = c("37.9067555 -122.0145836"), to = c("37.831217 -122.2719625"), mode = "driving",
+ output = "simple")
source to share
Here is a solution using Loop. Please note that I have changed the name of the input variables.
Input data
from <- c("37.8405983 -122.2544365",
"37.7589152 -122.4062322",
"37.7517621 -122.4062364",
"37.9659228 -122.505765",
"37.6969336 -121.8650777",
"37.9457334 -122.3152847",
"38.1237134 -122.23956",
"37.8911093 -122.2813663",
"37.9067555 -122.0145836",
"38.0673887 -122.2185562",
"37.7807761 -122.2102385",
"37.8911093 -122.2813663")
to <- c("37.8454493 -122.2833803",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625",
"37.831217 -122.2719625")
DF <- cbind(from, to); DF <- as.data.frame(DF) # create data frame
DF$from <- as.character(DF$from) # mapdist demands input to be character type
DF$to <- as.character(DF$to) # mapdist demands input to be character type
remove (from, to) #remove input to avoid confusion
DF$row.number <- 1:nrow(DF) #create an index number for each row
Loop - not commented
for (i in DF$row.number){
orig <- DF[i,c('from')]
dest <- DF[i,c('to')]
a <- mapdist(from = orig, to = dest, mode = "driving",output = "simple")
a$row.number <- i
DF$minutes[match(a$row.number, DF$row.number)] <- a$minutes
DF$hours[match(a$row.number, DF$row.number)] <- a$hours
DF$km[match(a$row.number, DF$row.number)] <- a$km
}
Loop - with comments
for (i in DF$row.number){
orig <- DF[i,c('from')] # get origin from DF in the position line 'i', column 'from'
dest <- DF[i,c('to')] # get origin from DF in the position line 'i', column 'to'
a <- mapdist(from = orig, to = dest, mode = "driving",output = "simple") # create temp. df 'a' with the output from mapdist
a$row.number <- i # include in temp. df 'a' the index number of the row from DF
DF$minutes[match(a$row.number, DF$row.number)] <- a$minutes # use the index number as a matching key to input/update the value of the variable 'minutes'
DF$hours[match(a$row.number, DF$row.number)] <- a$hours # ibdem DF$km[match(a$row.number, DF$row.number)] <- a$km #ibdem
DF$miles[match(a$row.number, DF$row.number)] <- a$miles # ibdem
}
ps.1 - Note that your code does not read O and D from the dataframe
ps.2 - I believe there is a simpler and more efficient way to solve this problem by combining function
andlapply
source to share