JRH06
JRH06

Reputation: 3

How to create a function to retrieve multiple cities historical weather using R and DARKSKY api?

I'm trying to retrieve historical weather data for 100 cities in R using DARKSKY API.

The following code works to get historical data for 1 city, however I'm having issues creating a loop function to go through a list of 100 latitude and longitudes and spit out the data.

weather <- function(Long,Lat) 
{ a <-seq(Sys.Date()-10, Sys.Date(), "1 day") %>%
  map(~get_forecast_for(Long,Lat,.x, units = 'si')) %>%
  map_df('daily')

write.csv(a,"blah blah")

}

weather(52.6983,-1.0735)

My initial thought was to upload csv file with all the longitude and latitudes I require. Set them as variables and then map them to the function above.

data <- read.csv("blah blah")
Long <- data$Longitude
Lat <- data$Latitude
map(c("Long","Lat"),weather)

But it keeps bringing back error messages.

Can anyone help please?

Thank you

Upvotes: 0

Views: 259

Answers (1)

dcruvolo
dcruvolo

Reputation: 669

You are almost there. There are a couple of things needed to iterate the get_forecast_for function by rows. From the purrr package, the pmap function is good for repeating a function by row whereas the imap function can be used for repeating a function by cells in a row.

Using this approach, I wrote two functions: weather_at_coords and weather. weather_at_coords is used to send a request to DarkSkyAPI for weather at specific location in a given time range (i.e., last ten days). The weather function is used to repeat the function by row.

I saw that you wanted the nested object daily, so wrote the function to extract that list from the response. I'm assuming that you also wanted the results in a data.frame so I added bind_rows. I added a column id so that rows can be properly linked to a location (or you can add any columns that you like).

# pkgs
library(tidyverse)
library(darksky)

# set API Key: free from https://darksky.net/dev
darksky::darksky_api_key()

# Forecast at a given point and time period
weather_at_coords <- function(...) {
  d <- rlang::list2(...)
  time <- seq(Sys.Date()-10, Sys.Date(), "1 day")
  response <- imap(time, ~ darksky::get_forecast_for(d$lat, d$lon, .x, units = "si")[["daily"]])
  out <- bind_rows(response) %>% mutate(id = d$id)
  return(out)
}

# primary function (iterates across rows)
weather <- function(data) {
  result <- pmap(data, ~ weather_at_coords(...))
  return(bind_rows(result))
}

# sample data
d <- data.frame(
  id = c("a", "b"),
  lat = c(37.8267,34.8267),
  lon = c(-122.423, -120.423)
)

# run
x <- weather(d)
x

Notes

  1. Make sure you have the rlang package installed
  2. Adjust the lat and lon variable names as required.

Upvotes: 0

Related Questions