Matt-Brigida / EIAdata

R Wrapper for the Energy Information Administration (EIA) API
16 stars 15 forks source link

R v4 returns date as character instead of factor #13

Closed Matt-Brigida closed 4 years ago

Matt-Brigida commented 4 years ago

Problem with this line:

date <- as.Date(paste(as.character(levels(df[,1]))[df[,1]], "-12-31", sep=""), "%Y-%m-%d")

need to remove the levels because in v4 R df[,1] is now a character. Should also refer to the dataframe columns by name instead of index.

sawyervillers commented 4 years ago

This isn't an issue, but I didn't know where to post. Maybe someone more skilled than I will write a new function for this package that will incorporate some of the code below.

EIAdata is a great package, but I need some of the other EIA data fields placed into a data.frame format for some large queries.

The EIA URL accepts either [&out=xml|json]. A microbenchmark (XML vs JSON) showed JSON is 8x faster, plus it has the benefit of unnesting cleanly.

And, yeah, I have a bazillion dependent packages because I'm lazy and work in the tidyverse.

library(jsonlite)
library(dplyr) #needed for piping and etc
library(purrr) #needed for map()
library(tidyr) #needed for unnest()
library(lubridate) #needed for floor_date

apikey<-'xxx'
series_ID<-'NG.N9020TX2.A'

url <- paste0("http://api.eia.gov/series?series_id=",series_ID,'&api_key=',apikey)

temp<-fromJSON(url)$series %>%
  mutate(data=map(data,as.data.frame)) %>%
  unnest(cols=data) %>%
  rename(datetext=V1,value=V2)

For posterity, here's my date parser:

  temp<-temp %>%  
    mutate(
      date=case_when(
        f=='A' ~ as.POSIXct(paste0(datetext,'-12-31'),format='%Y-%m-%d'), # Last day of the calendar year
        f=='Q' ~ floor_date(as.POSIXct(ceiling_date(yq(x),unit='quarter')),unit='day'), #painful gyrations to get 0:00 H:MM on last day of quarter        
        f=='M' ~ as.POSIXct(paste0(datetext,'01'),format='%Y%m%d'), #first day of month because I'm too lazy to use lubridate::days_in_month
        f=='W' ~ as.POSIXct(datetext,format='%Y%m%d'),
        f=='D' ~ as.POSIXct(datetext,format='%Y%m%d'),
        f=='H' ~ as.POSIXct(datetext,tz='UTC',format='%Y%m%dT%H'), # UTC "zulu" time
        f=='HL' ~ as.POSIXct(datetext,format='%Y%m%dT%H') #local time for region or balancing authority
        ))
Matt-Brigida commented 4 years ago

Thanks for the feedback. I am closing this issue, but I'll keep what you have written in mind when improving EIAdata.