0

I am trying to add a geom_vline in a function where the x-axis consists of dates. The plot shows NOK vs EUR, and the vertical lines are supposed to show up on dates with policy rate changes. The following code shows no vertical lines:

nok_eur_plot <- function(nok_eur_data, regression_method) {
  g <- ggplot(
      nok_eur_data, 
      aes(x = Date, y = NOK_EUR)
      ) + 
    geom_smooth(method = regression_method) +
    geom_point() + 
    labs(
      x = "Date", 
      y = paste("NOK per EUR for the last", length(nok_eur_data$NOK_EUR), "working-days", sep = " "),
      title = "NOK per EUR",
      subtitle = paste("From", min(nok_eur_data$Date), "to", max(nok_eur_data$Date), sep = " ")
      ) + 
    theme(
      axis.title.y = element_text(color = "blue")
      )

  rate_changes <- nok_key_policy_rate_change(length(nok_eur_data$NOK_EUR))

  for(row in 1:nrow(rate_changes)) {
    g + geom_vline(xintercept = rate_changes$Date[row], color = "red", size = 1, linetype = 4)
  }

  plot(g)
}

The result is this: enter image description here

I have tried changing the

xintercept = rate_changes$Date[row]

to

xintercept = as.numeric(rate_changes$Date[row])

and

xintercept = as.POSIXct(rate_changes$Date[row])

as suggested here, but to no avail. I have checked that there are rate changes present for the date range shown in the plot, and there are 3 of them.

The whole Rmd-script looks like this:

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library("xml2")
library("dplyr")
library("ggplot2")
library("scales")
```

## NOK vs EUR Regression

```{r, results='asis'}
analysis_periods <- c(10,100,200)

nok_eur <- function(days) {

  url_to_read <- paste(
    "https://data.norges-bank.no/api/data/EXR/",
    "B.EUR.NOK.SP?lastNObservations=",
    days,
    sep = ""
  )

  nok_eur_obs <- read_xml(url_to_read) %>%
    xml_find_all("//Obs")

  dates_closed <- nok_eur_obs %>% 
    xml_attr("TIME_PERIOD") %>% 
    as.Date("%Y-%m-%d")

  nok_eur_daily <- nok_eur_obs %>% 
    xml_attr("OBS_VALUE") %>% 
    as.numeric()

  nok_eur_data <- data.frame(x = dates_closed, y = nok_eur_daily)
  colnames(nok_eur_data) <- c("Date", "NOK_EUR")
  return(nok_eur_data)
}

nok_key_policy_rate_change <- function(days) {

  url_key_policy_rates <- "https://data.norges-bank.no/api/data/IR/B.KPRA.RR.R"

  key_policy_rates_obs <- read_xml(url_key_policy_rates) %>%
    xml_find_all("//Obs")

  key_policy_rates_subset <- key_policy_rates_obs[
    (length(key_policy_rates_obs) - days + 1):length(key_policy_rates_obs)
    ]

  dates_closed_rates <- key_policy_rates_subset %>%
    xml_attr("TIME_PERIOD") %>%
    as.Date("%Y-%m-%d")

  rates_daily <- key_policy_rates_subset %>%
    xml_attr("OBS_VALUE") %>%
    as.numeric()

  nok_key_policy_rate_data <- data.frame(x = dates_closed_rates, y = rates_daily)
  colnames(nok_key_policy_rate_data) <- c("Date", "Key_policy_rate")
  for(row in 1:nrow(nok_key_policy_rate_data)) {
    if(row == 1) {
      rate_change <- c(0)
    } else {
      change_from_previous <- nok_key_policy_rate_data$Key_policy_rate[row] - nok_key_policy_rate_data$Key_policy_rate[row - 1]
      rate_change <- c(rate_change, change_from_previous)
    }
  }
  nok_key_policy_rate_data["Change"] <- rate_change

  nok_key_policy_rate_change_data <- filter(nok_key_policy_rate_data, Change != 0)
  return(nok_key_policy_rate_change_data)

} 

nok_eur_plot <- function(nok_eur_data, regression_method) {
  g <- ggplot(
      nok_eur_data, 
      aes(x = Date, y = NOK_EUR)
      ) + 
    geom_smooth(method = regression_method) +
    geom_point() + 
    labs(
      x = "Date", 
      y = paste("NOK per EUR for the last", length(nok_eur_data$NOK_EUR), "working-days", sep = " "),
      title = "NOK per EUR",
      subtitle = paste("From", min(nok_eur_data$Date), "to", max(nok_eur_data$Date), sep = " ")
      ) + 
    theme(
      axis.title.y = element_text(color = "blue")
      )

  rate_changes <- nok_key_policy_rate_change(length(nok_eur_data$NOK_EUR))

  for(row in 1:nrow(rate_changes)) {
    g + geom_vline(xintercept = rate_changes$Date[row], colour = "red", size = 1, linetype = 4)
  }

  plot(g)
}

for(no_days in analysis_periods) {

  nok_eur_plot(nok_eur(no_days), "auto")
  nok_eur_plot(nok_eur(no_days), "lm")

}

The nok_eur_data dataframe (example with 5 days):

    Date <date> NOK_EUR <dbl>
1   2019-09-25  9.9310      
2   2019-09-26  9.9235      
3   2019-09-27  9.9155      
4   2019-09-30  9.8953      
5   2019-10-01  9.9463      
6   2019-10-02  9.9930  
...

The nok_key_policy_rate_change_data dataframe (example with 100 days):

    Date <date> Key_policy_rate <dbl> Change <dbl>
1   2019-06-21  0.25                  0.25  
2   2019-09-20  0.50                  0.25  

Any suggestions much appreciated.

ElToro1966
  • 831
  • 1
  • 8
  • 20
  • 2
    Without your data, all we can do is guess, but I'd guess that one problem is that in order to put `ggplot` commands inside a function, you've used `$` inside `aes`, which you [shouldn't](https://stackoverflow.com/questions/32543340/issue-when-passing-variable-with-dollar-sign-notation-to-aes-in-combinatio). Instead, the function needs to make use of [tidyeval](https://www.tidyverse.org/articles/2018/07/ggplot2-tidy-evaluation/). – camille Oct 08 '19 at 14:36
  • Thanks, @camille. Got rid of $ in the aes for the ggplot-statement, and added all data. Will have a look at tidyeval. Note that even with the change, the geom_vline is still not showing anything. – ElToro1966 Oct 08 '19 at 15:32

1 Answers1

2

The following loop in your code actually doesn't modify the graph:

for(row in 1:nrow(rate_changes)) {
    g + geom_vline(xintercept = rate_changes$Date[row], color = "red", size = 1, linetype = 4)
}

You should assign the result (i.e. g <- g + ...) in order to obtain an effect.

More efficient: remove the for loop and add all vertical lines in one go

g <- g + geom_vline(xintercept = rate_changes$Date, color = "red", size = 1, linetype = 4)
print(g)
Pierre Gramme
  • 1,209
  • 7
  • 23