Ottieni dati API con R

Esistono molti fantastici pacchetti R che ti consentono di importare dati da un'API con una singola funzione. Tuttavia, a volte un'API non ha una funzione già scritta. La buona notizia è che è facile codificare il tuo.

Lo dimostrerò con l'API AccuWeather, ma il processo e il codice funzioneranno per la maggior parte delle altre API che utilizzano una chiave per l'autenticazione.

Registrati per l'accesso all'API

Se vuoi seguire, vai su developer.accuweather.com e registrati per un account gratuito. In Pacchetti e prezzi, seleziona la versione di prova limitata, che consente 50 chiamate API al giorno, abbastanza se vuoi solo controllare le tue previsioni locali un paio di volte al giorno, ma ovviamente non per nessun tipo di applicazione pubblica.

Se non viene immediatamente presentata un'opzione per creare un'app, vai a Le mie app e crea una nuova app.

Sharon Machlis,

Ho scelto Altro per dove verrà utilizzata l'API, App interna per ciò che sto creando e Altro per il linguaggio di programmazione (purtroppo, R non è un'opzione). Alla tua app dovrebbe essere assegnata una chiave API.

Se non desideri codificare la chiave API nel tuo script di previsione AccuWeather, salvalo come variabile d'ambiente R. Il modo più semplice per farlo è utilizzare questo pacchetto. usethis::edit_r_environ() apre il file dell'ambiente R per la modifica. Aggiungi una riga come  ACCUWEATHER_KEY = 'my_key_string'a quel file, salva il file e riavvia la sessione R. È ora possibile accedere al valore della chiave  Sys.getenv("ACCUWEATHER_KEY")invece di codificare il valore stesso.

Determina la struttura dell'URL dell'API

Per questo progetto, caricherò prima i pacchetti httr, jsonlite e dplyr: httr per ottenere dati dall'API, jsonlite per analizzarli e dplyr per eventualmente utilizzare le pipe (puoi anche usare il pacchetto magrittr).

Successivamente, e questo è fondamentale, è necessario sapere come strutturare un URL per richiedere i dati desiderati dall'API . Capire la struttura della query può essere la parte più difficile del processo, a seconda di come è documentata l'API. Fortunatamente, i documenti dell'API di AccuWeather sono piuttosto buoni.

Qualsiasi query API richiede un URL di risorsa, o ciò che io considero la radice dell'URL e quindi parti specifiche della query. Ecco cosa dice AccuWeather nella sua documentazione per l'API di previsione di un giorno: 

 //dataservice.accuweather.com / forecasts / v1 / daily / 1day / {locationKey} 

L'URL di base per una previsione è per lo più costante, ma questo richiede un codice di posizione . Se stai solo cercando una previsione per una località, beh, puoi imbrogliare e utilizzare il sito Web di AccuWeather per cercare una previsione su accuweather.com e quindi controllare l'URL che torna. Quando cerco il codice postale 01701 (il nostro ufficio a Framingham, MA), il seguente URL ritorna insieme alla previsione: 

//www.accuweather.com/en/us/framingham/01701/weather-forecast/571_pc

Vedi /571_pcla fine? Questa è la chiave della posizione. Puoi anche utilizzare un'API AccuWeather Locations per estrarre i codici di posizione a livello di programmazione, che mostrerò tra poco, o uno degli strumenti API di AccuWeather per le posizioni basati sul web come City Search o Postal Code Search. 

Costruisci un URL di richiesta

I parametri di query per richieste di dati specifiche vengono aggiunti alla fine di un URL di base. Il primo parametro inizia con un punto interrogativo seguito dal nome uguale a valore. Eventuali coppie chiave-valore aggiuntive vengono aggiunte con una e commerciale seguita dal nome uguale a valore. Quindi, per aggiungere la mia chiave API, l'URL sarebbe simile a:

//dataservice.accuweather.com/forecasts/v1/daily/1day/571_pc?apikey=MY_KEY

Se volessi aggiungere un secondo parametro di query, ad esempio modificando i dettagli predefiniti da falso a vero, sarebbe simile a questo:

//dataservice.accuweather.com/forecasts/v1/daily/1day/571_pc?apikey=MY_KEY&details=true

Ottieni i dati

Possiamo usare la httr::GET()funzione per fare una GETrichiesta HTTP di quell'URL, come

my_url <- paste0 ("// dataservice.accuweather.com/forecasts/",

"v1 / daily / 1day / 571_pc? apikey =",

Sys.getenv ("ACCUWEATHER_KEY"))

my_raw_result <- httr :: GET (my_url)

Il paste0()comando che creava l'URL ha suddiviso la radice dell'URL in due righe per la leggibilità e quindi ha aggiunto la chiave API memorizzata nella variabile d'ambiente ACCUWEATHER_KEY R. 

my_raw_resultè un elenco piuttosto complesso. I dati effettivi che vogliamo sono principalmente nel contenuto, ma se guardi la sua struttura, vedrai che è un formato "grezzo" che assomiglia a dati binari.

Sharon Machlis,

Fortunatamente, il pacchetto httr semplifica la conversione da raw a un formato utilizzabile - con la content()funzione. 

Analizza i risultati

content()ti offre tre opzioni di conversione: come raw (che sicuramente non è utile in questo caso); parsed, che di solito sembra restituire una sorta di elenco; e testo. Per JSON, in particolare JSON annidato, trovo che il testo sia il più facile con cui lavorare. Ecco il codice:

my_content <- httr :: content (my_raw_result, as = 'text')

È qui che entra in gioco il pacchetto jsonlite. La fromJSON()funzione trasformerà una stringa di testo JSON da content()in un oggetto R più utilizzabile.

Ecco i risultati parziali dell'esecuzione della funzione dplyr glimpse()per my_contentdare un'occhiata alla struttura:

Sharon Machlis,

È un elenco con due elementi. Il primo elemento ha alcuni metadati e un campo di testo che potremmo desiderare. Il secondo elemento è un data frame con molti punti dati che vogliamo sicuramente per la previsione. 

L'esecuzione glimpse()su quel frame di dati mostra che era JSON nidificato, perché alcune delle colonne sono in realtà i loro frame di dati. Ma ha fromJSON()reso tutto abbastanza semplice.

Observations: 1 Variables: 8 $ Date  "2019-08-29T07:00:00-04:00" $ EpochDate  1567076400 $ Temperature   $ Day   $ Night   $ Sources  ["AccuWeather"]

So these are the basic steps to pulling data from an API:

  1. Figure out the API’s base URL and query parameters, and construct a request URL.
  2. Run httr::GET() on the URL. 
  3. Parse the results with content(). You can try it with as = 'parsed', but if that returns a complicated list, try as = 'text'.
  4. If necessary, run jsonlite::fromJSON() on that parsed object.

A couple of more points before we wrap up. First, if you look again at my_raw_result — the initial object returned from GET — you should see a status code. A 200 means all was OK. But a code in the 400s means something went wrong. If you’re writing a function or script, you can check whether the status code is in the 200s before additional code runs.

Second, if you’ve got multiple query parameters, it can get a little annoying to string them all together with a paste0() command. GET() has another option, which is creating a named list of query arguments, such as: 

my_raw_result2 <- GET(url,

query = list(

apikey = Sys.getenv("ACCUWEATHER_KEY"),

details = 'true'

)

)

Vedi la struttura? La GET()funzione accetta l'URL di base come primo argomento e un elenco di nomi e valori come secondo argomento della query. Ognuno è , con il nome non tra virgolette. Il resto del codice è lo stesso.name = value

Funziona anche con l'API AccuWeather Locations.

Ecco cosa sta cercando l'API:

Sharon Machlis,

Posso utilizzare un codice simile a quello dell'API di previsione, ma questa volta con i parametri di query apikeye q, rispettivamente, la chiave AccuWeather e il testo del luogo che sto cercando:

base_url <- "//dataservice.accuweather.com/locations/v1/cities/search"

ny_location_raw <- GET (base_url,

query = list (apikey = Sys.getenv ("ACCUWEATHER_KEY"),

q = "New York, NY"

))

ny_parsed%

fromJSON ()

Il codice posizione si trova nella colonna Chiave.

> glimpse (ny_parsed) Osservazioni: 1 Variabili: 15 $ Versione 1 $ Key "349727" $ Tipo "City" $ Rank 15 $ LocalizedName "New York" $ EnglishName "New York" $ PrimaryPostalCode "10007" $ Region $ Country $ AdministrativeArea $ TimeZone $ GeoPosition $ IsAlias ​​FALSE $ SupplementalAdminAreas []

Ora tutto ciò di cui hai bisogno è il codice per utilizzare i dati che hai estratto dall'API.

Per ulteriori suggerimenti su R, vai alla pagina "Fai di più con R" con una tabella di articoli e video ricercabili.