R code for Matrix trouble

Hi there,

I apologise in advance for this query as I assume it will be very easy to answer for most, however, I’m not well versed in R and I’m having to use it for a work project.

I have to calculate a ‘distance’ and ‘time’ between roughly 3000 postcodes via their longitude and latitude but I’m having issues setting up a data frame in R.

I have a column of longitudes and a column for latitudes for the origin postcodes and the exact same for the destination postcodes. These are all individuals and I would like to calculate their distance & time traveled.

My code:

coordinates <- data.frame(lon = c(Postcodes_Travel[["Longitude (Usual)"]],
                                  Postcodes_Travel[["Longitude (Dest)"]]),
                          lat = c(Postcodes_Travel[["Latitude (Usual)"]],
                                  Postcodes_Travel[["Latitude (Dest)"]]
                          ))
res <- ors_matrix(coordinates, metrics = c("duration", "distance"), units = "km")

This code generates a large matrix whilst all I’m looking for is a new column with Distance and one with Time
Person A: Origin → Dest = Distance + Time

Any help with this would be greatly appreciated as I’m at a loss.

Many thanks

Hi @julianosei

this is not really ORS specific, but basically data manipulation of dataframes in R.
Best read some examples on how to transform the matrix output.

Best regards

Hello,

I recently made code to generate distance and time matrices between more than 5000 geographic points in R. I hope it can help you.

######################################################

library(jsonlite)
library(httr)
entremunics<-function(coordl) {
  require("jsonlite")
  require("httr")  
  coord<-coordl # coordl is  coordinate matrix
  # the columns must be [longitude, latitude] in that order  in the array.
  body<-list(locations=coord,
             metrics=list("distance","duration"),
             units="km")
  body <-  toJSON(body, auto_unbox = TRUE)
  url<-'https://api.openrouteservice.org/v2/matrix/driving-car'
  
  r <- POST(url,body = body, 
            add_headers(`Accept` = "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8"),
            add_headers(`Authorization`= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),
            add_headers(`Content-Type`= "application/json; charset=utf-8"))
  
  h<-r$content
  data0<-fromJSON(rawToChar(as.raw(strtoi(h, 16L))))
  data0$restantes<-as.numeric(r$headers$`x-ratelimit-remaining`) # key request limits
  return(data0)
}


coords<-read.csv("geographic coordinates.csv")
coords<-coords[order(coords$cod_ibge),] # names or code of each point

distance<-diag(nrow(coords)) # identity matrix
#distance<-as.matrix(fst::read_fst("distance_km.fst")) # retrieve the matrix from where it left off
durations<-diag(nrow(coords)) 
#durations<-as.matrix(fst::read_fst("durations_seconds.fst")) # retrieve the matrix from where it left off
rownames(distance)<-rownames(durations)<-coords$cod_ibge
colnames(distance)<-colnames(durations)<-coords$cod_ibge
i<-seq(1,nrow(coords),by=25) # 50 geographic coordinate points is the limit of requests per matrix
j<-c(i[-1]-1,nrow(coords))  # allowing 25 fixed points of origin to 25 variant points of destination (or the opposite)
# loopin  to fill the matrix
for (k1 in 1:(length(i)-1)) {
  s1<-c(i[k1]:j[k1])
  for (k2 in k1:(length(i)-1)) {
    s2<-i[k2+1]:j[k2+1]
    coordl<-as.matrix(coords[c(s1,s2),4:3]) # the columns must be [longitude, latitude] in that order  in the array.
    distbetween<-entremunics(coordl)
    distance[c(s1,s2),c(s1,s2)]<-distbetween$distances
    durations[c(s1,s2),c(s1,s2)]<-distbetween$durations
    Sys.sleep(2)  # pause to respect api limitations
    # .3 to .8 seconds for 50 or 40 requests per minute varies with the internet speed at the time. 
    # I put in 2 seconds because there were often access cuts.
   # Even with a key with permissions of up to 25 thousand requests a day.  
    if(distbetween$restantes==1){  
     # to meet the site's daily restrictions limit
      break
    }
  }
  # save if there is an error to not start from the beginning.
  df.distance<-as.data.frame(distance)
  fst::write_fst(df.distance,"distance_km.fst", compress = 0)
  df.durations<-as.data.frame(durations)
  fst::write_fst(df.durations,"durations_seconds.fst", compress = 0)

  if(distbetween$restantes<(length(i)-k1)){
     # to meet the site's daily restrictions limit
    break
  }
  cat(k1, "-")
}


df.distance<-as.data.frame(distance)
df.distance$cod_munic<-coords$cod_ibge
fst::write_fst(df.distance,"distance_km.fst", compress = 100)

df.durations<-as.data.frame(durations)
df.durations$cod_munic<-coords$cod_ibge
fst::write_fst(df.durations,"durations_seconds.fst", compress = 100)


df.durations<-durations/(60*60) # duration for seconds to hours 
df.durations<-round(df.durations,3) 
df.durations<-as.data.frame(df.durations)
df.durations$cod_munic<-coords$codigo_ibge
fst::write_fst(df.durations,"durations_hours.fst", compress = 100)
1 Like