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

后端 未结 3 1694
轮回少年
轮回少年 2021-02-09 17:46

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

相关标签:
3条回答
  • 2021-02-09 18:20

    You can do this without an API, just using the co-ordinates of airports, which are available freely in a database here https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat

    ## Import airport data
    airports <- read.csv("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat", header = F)
    
    library(geosphere)
    ## Calculate matrix of differences in km
    distance.matrix <- distm(x = airports[,c("V8", "V7")],  y = airports[,c("V8", "V7")])/1000
    ## This may take a while, and will generate a matrix 8107 by 8107, about 0.5gb in size.
    
    ## Rename dimensions to airport codes
    rownames(distance.matrix) <- airports$V5
    colnames(distance.matrix) <- airports$V5
    
    ## Example: km between Gatwick and Heathrow
    distance.matrix["LGW", "LHR"]
    [1] 41.24091
    
    0 讨论(0)
  • 2021-02-09 18:27

    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
    
    0 讨论(0)
  • 2021-02-09 18:33

    What about the following loop over your api calls?

    df$distance <- 0
    
    for (i in nrow(df)){
      drs <- df[i,]$departure
      fue <- df[i,]$arrival
      url <- paste0("https://airport.api.aero/airport/distance/", drs, "/", fue, "?user_key=4e816a2bf391f8379df1c42d2762069e")
      api <- curl_fetch_memory(url)
      text <- rawToChar(api$content)
      distance <- as.numeric(gsub(',','',substr(text,regexpr('distance',text)+11,regexpr('units',text)-4)))
      df[1,]$distance <- distance
    }
    
    df
    
    0 讨论(0)
提交回复
热议问题