2016-06-01 20 views
6

Mi chiedevo se ci fosse un modo per confrontare le distanze dell'aeroporto (codici IATA). Ci sono alcuni script, ma non utilizza R. Così ho provato che con con l'API:Utilizzo di un'API per calcolare la distanza tra due aeroporti (due colonne) all'interno di R?

developer.aero

dati Esempio:

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"}) 

dove DRS corrisponde per l'aeroporto di partenza e di arrivo FUE

Quindi, devo eseguire il ciclo su df e incollarlo nell'URL. Tuttavia, che sembra in qualche modo difficile per un 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="|") 
} 

output desiderato:

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 
+1

Ottieni le distanze quando esegui 'read.table' e la tua domanda è come salvarle in un data.frame? O ottieni solo i geocoordinati degli aeroporti e la tua domanda riguarda come trasformarli in distanze? Oppure la tua domanda sul collegamento dei codici IATA ai geocoordinati? – Qaswed

+0

Se ci fosse stata qualche risposta positiva alla richiesta di chiarimenti, non ci saremmo uniti al suggerimento closevote, ma con l'errore lanciato dalla seconda sezione del codice non è chiaro cosa sia stato chiesto. –

risposta

6

Ecco un altro modo con il pacchetto httr:

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 

Se si desidera ottenere i risultati completi, è possibile utilizzare:

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

fantastico. grazie!! –

+0

Posso chiederti un'ulteriore informazione su come regolare il ciclo for se la distanza tra aiports è "NULL". Suppongo che il ciclo si fermerà. Grazie ancora! –

+1

@MichaerMacher Vorrei consigliare questa domanda come una nuova domanda. Inoltre, potresti probabilmente cambiare le ultime due righe del ciclo 'for' su:' distance <- ifelse (is.null (callAPI (from, to) $ distance), NA, callAPI (from, to) $ distance) 'e' df [i, "distanza"] <- distanza'. In questo modo restituiresti un 'NA' per indagare. – JasonAizkalns

1

E il ciclo seguente sopra le chiamate API?

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 
7

È possibile fare questo senza un'API, usando solo le coordinate degli aeroporti, che sono disponibili liberamente in un database qui 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 
Problemi correlati