Obtenga datos de API con R

Hay muchos paquetes R excelentes que le permiten importar datos desde una API con una sola función. Sin embargo, a veces una API no tiene una función ya escrita. La buena noticia es que es fácil codificar el tuyo.

Lo demostraré con la API de AccuWeather, pero el proceso y el código funcionarán para la mayoría de las otras API que usan una clave para la autenticación.

Regístrese para acceder a la API

Si desea seguirlo, vaya a developer.accuweather.com y regístrese para obtener una cuenta gratuita. En Paquetes y precios, seleccione Prueba limitada, que permite 50 llamadas a la API por día, suficiente si solo desea verificar su pronóstico local un par de veces al día, pero obviamente no para ningún tipo de aplicación de cara al público.

Si no se le presenta inmediatamente una opción para crear una aplicación, vaya a Mis aplicaciones y cree una nueva aplicación.

Sharon Machlis,

Elegí Otro para dónde se usará la API, Aplicación interna para lo que estoy creando y Otro para el lenguaje de programación (lamentablemente, R no es una opción). Su aplicación debe tener asignada una clave API.

Si no desea codificar esa clave API en su script de pronóstico de AccuWeather, guárdelo como una variable de entorno R. La forma más sencilla de hacer esto es usando este paquete. usethis::edit_r_environ() abre su archivo de entorno R para editarlo. Agregue una línea como  ACCUWEATHER_KEY = 'my_key_string'a ese archivo, guarde el archivo y reinicie su sesión de R. Ahora puede acceder al valor de la clave en  Sys.getenv("ACCUWEATHER_KEY")lugar de codificar el valor en sí.

Determine la estructura de la URL de la API

Para este proyecto, primero cargaré los paquetes httr, jsonlite y dplyr: httr para obtener datos de la API, jsonlite para analizarlos y dplyr para eventualmente usar tuberías (también puede usar el paquete magrittr).

A continuación, y esto es fundamental, debe saber cómo estructurar una URL para solicitar los datos que desea de la API . Averiguar la estructura de la consulta puede ser la parte más difícil del proceso, dependiendo de qué tan bien esté documentada la API. Afortunadamente, los documentos de la API de AccuWeather son bastante buenos.

Cualquier consulta de API necesita una URL de recurso, o lo que yo considero la raíz de la URL, y luego partes específicas de la consulta. Esto es lo que dice AccuWeather en su documentación para la API de pronóstico de un día: 

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

La URL base para un pronóstico es mayormente constante, pero esta necesita un código de ubicación . Si solo está buscando un pronóstico para una ubicación, bueno, puede hacer trampa y usar el sitio web de AccuWeather para buscar un pronóstico en accuweather.com y luego verificar la URL que regresa. Cuando busco el código postal 01701 (nuestra oficina en Framingham, MA), la siguiente URL aparece junto con el pronóstico: 

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

¿Ves el /571_pcal final? Esa es la clave de ubicación. También puede utilizar una API de ubicaciones de AccuWeather para extraer códigos de ubicación mediante programación, que mostraré en un momento, o una de las herramientas de API de ubicaciones basadas en la web de AccuWeather, como Búsqueda de ciudad o Búsqueda de código postal. 

Construya una URL de solicitud

Los parámetros de consulta para solicitudes de datos específicas se agregan al final de una URL base. El primer parámetro comienza con un signo de interrogación seguido de nombre es igual a valor. Cualquier par clave-valor adicional se agrega con un ampersand seguido de name es igual a valor. Entonces, para agregar mi clave API, la URL se vería así:

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

Si quisiera agregar un segundo parámetro de consulta, por ejemplo, cambiar los detalles predeterminados de falso a verdadero, se vería así:

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

Obtener los datos

Podemos usar la httr::GET()función para realizar una GETsolicitud HTTP de esa URL, como

my_url <- paste0 ("// servicio de datos.accuweather.com/forecasts/",

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

Sys.getenv ("ACCUWEATHER_KEY"))

my_raw_result <- httr :: GET (my_url)

Ese paste0()comando que crea la URL dividió la raíz de la URL en dos líneas para facilitar la lectura y luego agregó la clave API almacenada en la variable de entorno ACCUWEATHER_KEY R. 

my_raw_resultes una lista algo compleja. Los datos reales que queremos están principalmente en contenido, pero si miras su estructura, verás que es un formato "sin procesar" que parece datos binarios.

Sharon Machlis,

Afortunadamente, el paquete httr facilita la conversión de formato sin formato a un formato utilizable, con la content()función. 

Analizar los resultados

content()le ofrece tres opciones de conversión: en bruto (que definitivamente no es útil en este caso); analizado, que normalmente parece devolver algún tipo de lista; y texto. Para JSON, especialmente JSON anidado, encuentro que el texto es el más fácil de trabajar. Aquí está el código:

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

Aquí es donde entra el paquete jsonlite. La fromJSON()función convertirá una cadena de texto JSON content()en un objeto R más utilizable.

Aquí hay resultados parciales de ejecutar la glimpse()función de dplyr my_contentpara ver la estructura:

Sharon Machlis,

Es una lista con dos elementos. El primer elemento tiene algunos metadatos y un campo de texto que podríamos querer. El segundo elemento es un marco de datos con muchos puntos de datos que definitivamente queremos para el pronóstico. 

Ejecutar glimpse()solo en ese marco de datos muestra que fue JSON anidado, porque algunas de las columnas son en realidad sus propios marcos de datos. Pero lo fromJSON()hizo todo bastante perfecto.

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'

)

)

¿Ves la estructura? La GET()función toma la URL base como primer argumento y una lista de nombres y valores como segundo argumento de consulta. Cada uno es , con el nombre no entre comillas. El resto del código es el mismo.name = value

Eso también funciona para la API de ubicaciones de AccuWeather.

Esto es lo que busca la API:

Sharon Machlis,

Puedo usar un código similar al de la API de pronóstico, pero esta vez con los parámetros de consulta apikeyy qla clave AccuWeather y el texto del lugar que estoy buscando, respectivamente:

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

ny_location_raw <- OBTENER (base_url,

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

q = "Nueva York, NY"

))

ny_parsed%

fromJSON ()

El código de ubicación está en la columna Clave.

> glimpse (ny_parsed) Observaciones: 1 Variables: 15 $ Versión 1 $ Clave "349727" $ Tipo "Ciudad" $ Rango 15 $ LocalizedName "Nueva York" $ EnglishName "Nueva York" $ PrimaryPostalCode "10007" $ Región $ País $ Área administrativa $ TimeZone $ GeoPosition $ IsAlias ​​FALSE $ SupplementalAdminAreas []

Ahora todo lo que necesita es código para usar los datos que ha extraído de la API.

Para obtener más sugerencias de R, diríjase a la página "Haga más con R" con una tabla de artículos y videos que permite realizar búsquedas.