Search code examples
rrcurlhttr

Using an API to calculate distance between two airports (two columns) within R?


I was wondering whether there was a way to compare airport distances(IATA codes). There are some scripts but not is using R. So I tried that with with the API:

developer.aero

Example data:

library(curl) # for curl post

departure <- c("DRS","TXL","STR","DUS","LEJ","FKB","LNZ")
arrival <- c("FKB","HER","BOJ","FUE","PMI","AYT","FUE")
flyID <- c(1,2,3,4,5,6,7)
df <- data.frame(departure,arrival,flyID)  

     departure arrival flyID
1       DRS     FKB     1
2       TXL     HER     2
3       STR     BOJ     3
4       DUS     FUE     4
5       LEJ     PMI     5
6       FKB     AYT     6
7       LNZ     FUE     7

api<- curl_fetch_memory("https://airport.api.aero/airport/distance/DRS/FUE?user_key=d805e84363494ca03b9b52d5a505c4d1")

cat(rawToChar(api$content))

callback({"processingDurationMillis":0,"authorisedAPI":true,"success":true,"airline":null,"errorMessage":null,"distance":"3,416.1","units":"km"})

where DRS corresponds to departure and FUE arrival airport

So I though to loop over dfand paste into url. However that seems somehow difficult for a R - Newbie

df$distance<- list(length = nrow(df))
for (i in 1:nrow(df)){
  url <- paste0("https://airport.api.aero/airport/distance/", i, "FUE   ?user_key=d805e84363494ca03b9b52d5a505c4d1")
  myData[[i]] <- read.table(url, header=T,sep="|")
}

Desired Output:

departure arrival flyID    distance
1       DRS     FKB     1    1000
2       TXL     HER     2    499
3       STR     BOJ     3    300
4       DUS     FUE     4    200
5       LEJ     PMI     5    586
6       FKB     AYT     6   10292
7       LNZ     FUE     7   3939

Solution

  • Here's another way with the httr package:

    library(httr)
    
    callAPI <- function(from, to) {
      res <- GET("https://airport.api.aero",
                 path = paste0("airport/distance/", from, "/", to),
                 query = list(user_key = "d805e84363494ca03b9b52d5a505c4d1"))
      stop_for_status(res)
      return(content(res, encoding = "UTF-8"))
    }
    
    
    test <- callAPI("DRS", "FKB")
    # test
    test$distance
    # [1] "484.6"
    
    for (i in 1:nrow(df)) {
      from = df[i, "departure"]
      to = df[i, "arrival"]
      df[i, "distance"] <- callAPI(from, to)$distance
    }
    
    #   departure arrival flyID distance
    # 1       DRS     FKB     1    484.6
    # 2       TXL     HER     2  2,131.8
    # 3       STR     BOJ     3  1,575.0
    # 4       DUS     FUE     4  3,066.3
    # 5       LEJ     PMI     5  1,512.4
    # 6       FKB     AYT     6  2,264.2
    # 7       LNZ     FUE     7  3,258.0
    

    If you want to get the full results, you could use:

    all_results <- mapply(function(x,y) { callAPI(x,y) }, df$departure, df$arrival)
    cbind(df, t(all_results))
    #   departure arrival flyID processingDurationMillis authorisedAPI success airline errorMessage distance units
    # 1       DRS     FKB     1                        0          TRUE    TRUE    NULL         NULL    484.6    km
    # 2       TXL     HER     2                        0          TRUE    TRUE    NULL         NULL  2,131.8    km
    # 3       STR     BOJ     3                        0          TRUE    TRUE    NULL         NULL  1,575.0    km
    # 4       DUS     FUE     4                        0          TRUE    TRUE    NULL         NULL  3,066.3    km
    # 5       LEJ     PMI     5                        0          TRUE    TRUE    NULL         NULL  1,512.4    km
    # 6       FKB     AYT     6                        0          TRUE    TRUE    NULL         NULL  2,264.2    km
    # 7       LNZ     FUE     7                        1          TRUE    TRUE    NULL         NULL  3,258.0    km