Obtenez des données API avec R

Il existe de nombreux packages R qui vous permettent d'importer des données à partir d'une API avec une seule fonction. Cependant, parfois, une API n'a pas de fonction déjà écrite. La bonne nouvelle est qu'il est facile de coder le vôtre.

Je vais le démontrer avec l'API AccuWeather, mais le processus et le code fonctionneront pour la plupart des autres API qui utilisent une clé pour l'authentification.

Inscrivez-vous pour accéder à l'API

Si vous voulez suivre, allez sur developer.accuweather.com et inscrivez-vous pour un compte gratuit. Sous Forfaits et tarification, sélectionnez l'essai limité, qui autorise 50 appels d'API par jour - assez si vous souhaitez simplement vérifier vos prévisions locales plusieurs fois par jour, mais évidemment pas pour toute sorte d'application publique.

Si vous ne disposez pas immédiatement d'une option pour créer une application, accédez à Mes applications et créez une nouvelle application.

Sharon Machlis,

J'ai choisi Autre pour l'endroit où l'API sera utilisée, Application interne pour ce que je crée et Autre pour le langage de programmation (malheureusement, R n'est pas une option). Votre application doit recevoir une clé API.

Si vous ne souhaitez pas coder en dur cette clé API dans votre script de prévision AccuWeather, enregistrez-la en tant que variable d'environnement R. Le moyen le plus simple de le faire est d'utiliser ce package. usethis::edit_r_environ() ouvre votre fichier d'environnement R pour le modifier. Ajoutez une ligne comme  ACCUWEATHER_KEY = 'my_key_string'à ce fichier, enregistrez le fichier et redémarrez votre session R. Vous pouvez maintenant accéder à la valeur de clé avec  Sys.getenv("ACCUWEATHER_KEY")au lieu de coder en dur la valeur elle-même.

Déterminer la structure URL de l'API

Pour ce projet, je vais d'abord charger les packages httr, jsonlite et dplyr: httr pour obtenir les données de l'API, jsonlite pour les analyser et dplyr pour éventuellement utiliser des tubes (vous pouvez également utiliser le package magrittr).

Ensuite - et c'est essentiel - vous devez savoir comment structurer une URL afin de demander les données souhaitées à l'API . Déterminer la structure de la requête peut être la partie la plus difficile du processus, en fonction de la qualité de la documentation de l'API. Heureusement, la documentation de l'API AccuWeather est plutôt bonne.

Toute requête d'API nécessite une URL de ressource, ou ce que je considère comme la racine de l'URL, puis des parties spécifiques de la requête. Voici ce que dit AccuWeather dans sa documentation pour l'API de prévision d'un jour: 

 //dataservice.accuweather.com / prévisions / v1 / daily / 1day / {locationKey} 

L'URL de base d'une prévision est généralement constante, mais celle-ci nécessite un code de localisation . Si vous recherchez simplement une prévision pour un endroit, eh bien, vous pouvez tricher et utiliser le site Web AccuWeather pour rechercher une prévision sur accuweather.com, puis vérifier l'URL qui revient. Lorsque je recherche le code postal 01701 (notre bureau à Framingham, MA), l'URL suivante revient avec les prévisions: 

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

Vous voyez le /571_pcà la fin? C'est la clé de localisation. Vous pouvez également utiliser une API de localisation AccuWeather pour extraire des codes de localisation par programmation, que je montrerai dans un instant, ou l'un des outils de l'API de localisation basée sur le Web d'AccuWeather, tels que la recherche par ville ou la recherche par code postal. 

Construire une URL de requête

Les paramètres de requête pour des demandes de données spécifiques sont placés à la fin d'une URL de base. Le premier paramètre commence par un point d'interrogation suivi de nom égal à valeur. Toutes les paires clé-valeur supplémentaires sont ajoutées avec une esperluette suivie de nom égal à valeur. Donc, pour ajouter ma clé API, l'URL ressemblerait à:

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

Si je voulais ajouter un deuxième paramètre de requête - disons, changer les détails par défaut de false à true - cela ressemblerait à ceci:

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

Obtenez les données

Nous pouvons utiliser la httr::GET()fonction pour faire une GETrequête HTTP de cette URL, telle que

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

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

Sys.getenv ("ACCUWEATHER_KEY"))

my_raw_result <- httr :: GET (mon_url)

Cette paste0()commande créant l'URL a divisé la racine de l'URL en deux lignes pour plus de lisibilité, puis a ajouté la clé API stockée dans la variable d'environnement ACCUWEATHER_KEY R. 

my_raw_resultest une liste quelque peu complexe. Les données réelles que nous voulons sont principalement dans le contenu, mais si vous regardez sa structure, vous verrez que c'est un format «brut» qui ressemble à des données binaires.

Sharon Machlis,

Heureusement, le package httr facilite la conversion du format brut vers un format utilisable - avec la content()fonction. 

Analyser les résultats

content()vous propose trois options de conversion: comme brut (ce qui n'est certainement pas utile dans ce cas); parsed, qui semble généralement retourner une sorte de liste; et texte. Pour JSON - en particulier JSON imbriqué - je trouve que le texte est le plus simple à utiliser. Voici le code:

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

C'est là que le package jsonlite entre en jeu. La fromJSON()fonction transformera une chaîne de texte JSON content()en un objet R plus utilisable.

Voici les résultats partiels de l' exécution de dplyr glimpse()fonction sur my_contentpour obtenir un oeil à la structure:

Sharon Machlis,

C'est une liste avec deux éléments. Le premier élément a des métadonnées et un champ de texte que nous pourrions vouloir. Le deuxième élément est une base de données avec beaucoup de points de données que nous voulons absolument pour les prévisions. 

L'exécution glimpse()de cette seule trame de données montre qu'il s'agissait d'un JSON imbriqué, car certaines des colonnes sont en fait leurs propres trames de données. Mais fromJSON()rendu tout cela assez transparent.

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'

)

)

Vous voyez la structure? La GET()fonction prend l'URL de base comme premier argument et une liste de noms et de valeurs comme deuxième argument de requête. Chacun est , avec le nom pas entre guillemets. Le reste du code est le même.name = value

Cela fonctionne également pour l'API AccuWeather Locations.

Voici ce que recherche l'API:

Sharon Machlis,

Je peux utiliser un code similaire à celui de l'API de prévision, mais cette fois avec les paramètres de requête apikeyet q, la clé AccuWeather et le texte de l'endroit que je recherche, respectivement:

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%

depuisJSON ()

Le code d'emplacement se trouve dans la colonne Clé.

> glimpse (ny_parsed) Observations: 1 Variables: 15 $ Version 1 $ Clé "349727" $ Type "Ville" $ Rang 15 $ LocalizedName "New York" $ EnglishName "New York" $ PrimaryPostalCode "10007" $ Région $ Pays $ AdministrativeArea $ TimeZone $ GeoPosition $ IsAlias ​​FALSE $ SupplementalAdminAreas []

Il vous suffit désormais de code pour utiliser les données que vous avez extraites de l'API.

Pour plus de conseils sur R, accédez à la page «Faites plus avec R» avec un tableau d'articles et de vidéos consultables.