Calling an API within a mutate statement in R

Viewed 111

I am attempting to determine the sunrise time of a given date using an API

So I have a dataframe like so

        Date
1 2018-01-03
2 2018-01-03
3 2018-01-04
4 2018-01-08
5 2018-01-09

And while I can get it to work without a paste statement, when I throw it into a mutate, it does not work and returns an error:

dates <- structure(list(Date = c("2018-01-03", "2018-01-03", "2018-01-04", 
"2018-01-08", "2018-01-09")), row.names = c(NA, 5L), class = "data.frame")


dates %>% 
  mutate(sunrise = as.character(fromJSON(rawToChar(GET(paste0("https://api.sunrise-sunset.org/json?lat=40.730610&lng=-73.935242&date=", Date))$content))$results[1])
           )

ERROR:
Error: Problem with `mutate()` input `sunrise`.
x length(url) == 1 is not TRUE
i Input `sunrise` is `as.character(...)`.

What the goal here is I want to have a new column of sunrises for each of the days. It works perfectly if I change the paste0 field and give it an exact string, but not in the mutate and I cant figure why...

2 Answers

This can be achieved via dplyr::rowwise

library(dplyr)
library(httr)
library(jsonlite)

dates <- structure(list(Date = c("2018-01-03", "2018-01-03", "2018-01-04", 
                                 "2018-01-08", "2018-01-09")), row.names = c(NA, 5L), class = "data.frame")

dates %>% 
  rowwise() %>% 
  mutate(sunrise = as.character(fromJSON(rawToChar(GET(paste0("https://api.sunrise-sunset.org/json?lat=40.730610&lng=-73.935242&date=",Date))$content))$results[1]))
#> # A tibble: 5 x 2
#> # Rowwise: 
#>   Date       sunrise    
#>   <chr>      <chr>      
#> 1 2018-01-03 12:19:53 PM
#> 2 2018-01-03 12:19:53 PM
#> 3 2018-01-04 12:19:52 PM
#> 4 2018-01-08 12:19:27 PM
#> 5 2018-01-09 12:19:15 PM

Another option is map from purrr

library(dplyr)
library(purrr)
library(jsonlite)
dates %>%
     mutate(sunrise = map_chr(sprintf("https://api.sunrise-sunset.org/json?lat=40.730610&lng=-73.935242&date=%s", Date), 
         ~ as.character(fromJSON(rawToChar(GET(.x)$content))$results[1])))
#        Date     sunrise
#1 2018-01-03 12:19:53 PM
#2 2018-01-03 12:19:53 PM
#3 2018-01-04 12:19:52 PM
#4 2018-01-08 12:19:27 PM
#5 2018-01-09 12:19:15 PM

data

dates <- structure(list(Date = c("2018-01-03", "2018-01-03", "2018-01-04", 
"2018-01-08", "2018-01-09")), row.names = c(NA, 5L), class = "data.frame")
Related