R/np_prices.R

Defines functions np_prices

Documented in np_prices

#' Get the spot prices for a specified price_date.
#'
#' The function will return hourly, daily, weekly,
#' monthly or yearly spot prices. The hourly prices
#' are the prices the Nordic end users pay and the price
#' which the producers get. The daily,
#' weekly, monthly and yearly prices are base (mean over a period)
#' and not necessarily equal to the price the end user pays
#' or the price the producer gets, as the consumption and
#' production is not flat. Learn more at the website.
#'
#' @param time_unit The time unit to return the data in.
#' @param currency Price currency. EUR, NOK, DKK or SEK.
#' @param price_date Date class object. The default is for tomorrow.
#' @param areas A character vector with the areas you are interested in. Defaults to all.
#' @param long_data Boolean. Do you want the data returned as a long or wide data.frame?
#' @importFrom dplyr %>%
#' @export
#' @references \url{http://nordpoolspot.com/How-does-it-work/}
#' @examples
#'   # Get the prices for tommorow.
#'   np_prices("hourly", "EUR")
#'
#'   # Get the prices for today
#'   np_prices("hourly", "EUR", Sys.Date())
#'
#'   # Get a long data frame
#'   np_prices("hourly", "EUR", long_data = TRUE)
#'
#'   # Get only the Danish prices in DKK
#'   np_prices(time_unit = "hourly", currency = "DKK", areas = c("DK1", "DK2"))
np_prices <- function(time_unit = c("hourly", "daily", "weekly", "monthly", "yearly"),
                      currency = c("EUR", "NOK", "DKK", "SEK"),
                      price_date = Sys.Date() + lubridate::days(1),
                      areas = NULL,
                      long_data = FALSE){

  ## Checks and balances
  # is prices_date a date object
  # is time_unit one of the correct values
  # is currency one of the correct values
  if(!lubridate::is.Date(price_date)) stop("The price_date param needs to be an object of the class Date.")

  if(time_unit[1] == "hourly"){
    page <- 10
  } else if(time_unit[1] == "daily"){
    page <- 11
  } else if(time_unit[1] == "weekly"){
    page <- 12
  } else if(time_unit[1] == "monthly"){
    page <- 13
  } else if(time_unit[1] == "yearly"){
    page <- 14
  } else {stop("time_unit can only be one of the following: hourly, daily, weekly, monthly, yearly")}

  if(currency[1] != "EUR" & currency[1] != "DKK" & currency[1] != "NOK" & currency[1] != "SEK"){
    stop("currency can only be one of the following: EUR, DKK, NOK or SEK")
  }

  ## Get the data.
  np <-
    httr::GET(paste0("http://www.nordpoolgroup.com/api/marketdata/page/", page,
                     "?currency=,", currency, currency, currency,
                     "&endDate=", strftime(price_date, "%d-%m-%Y")))

  ## Get the content
  # The list is rather nasty and we need date, area and spot prices
  # from two places in the list. We'll create a data.frame with
  # the dates and then nest a list with the area name and spot
  # prices. The procedure is a two part proces. In the end the
  # nested lists will be unnested using tidyr.

  # subset until rows and get the start and end time.
  # The IsExtraRow variable is TRUE for summary data,
  # wich I'm not interested in.
  np_data <-
    np %>%
    httr::content() %>%
    .[["data"]] %>%
    .[["Rows"]] %>%
    purrr::map_df(`[`, c("StartTime", "EndTime", "IsExtraRow")) %>%
    # Insert a nested list with the name price list.
    # Subset until the rows data and
    # extract the Name (which is the area), Value (which is the spot price)
    # and IsAdditionalData.
    dplyr::mutate(price_lists = np %>%
                    httr::content() %>%
                    .[["data"]] %>%
                    .[["Rows"]] %>%
                    purrr::map("Columns") %>%
                    purrr::map(function(x){x %>%
                        purrr::map_df(`[`, c("Name", "Value", "IsAdditionalData")) %>%
                        # I supress warnings as there are empty (NA) rows (indicated by IsExtraRow) that gives warnings when
                        # they are parsed. I remove these rows below.
                        dplyr::mutate(Value = suppressWarnings(as.numeric(stringr::str_replace(Value, ",", "."))))})) %>%
    # Unnest the data.frame with the nested list. This creates a long data.frame.
    tidyr::unnest(price_lists) %>%
    dplyr::mutate(StartTime = lubridate::ymd_hms(StartTime, tz = "CET"),
                  EndTime = lubridate::ymd_hms(EndTime, tz = "CET")) %>%
    # Remove the unwanted summary data.
    dplyr::filter(!IsExtraRow) %>%
    dplyr::select(-IsExtraRow, -IsAdditionalData) %>%
    # Rename the variable Name to Areas as this is a better name.
    dplyr::rename(Areas = Name)

  # subset areas
  if(!is.null(areas)){
    np_data <- np_data[np_data$Areas %in% areas, ]
    rm("areas")
  }

  np_data <-
    np_data %>%
    dplyr::filter(!is.na(Value))

  # Make data wide
  if(!long_data){
    np_data <-
      np_data %>%
      tidyr::pivot_wider(names_from = Areas, values_from = Value)
  }

  if(!price_date %in% lubridate::as_date(np_data$StartTime)){
    stop(paste("The price_date is not the same as the date in the data returned from the API:", unique(lubridate::as_date(np_data$StartTime))))
  }

  np_data
}
krose/nordpoolspotr documentation built on Dec. 11, 2021, 8:09 p.m.