/ R-Project

Creating R Charts with Dual Axes in R

Charts with dual axes have been a hot debate topic for quite a while now. I see merits in the arguments against using Dual Axes but then I often them convienient too.

I came across this post from R-Bloggers on creating Dual axes time series plots

Modified it slightly to get to the part of interest to me. Original source is available here

usePackage <- function(p) 
{
  if (!is.element(p, installed.packages()[,1]))
    install.packages(p, dep = TRUE)
  require(p, character.only = TRUE)
}

usePackage('readxl')
usePackage('dplyr')
usePackage('tidyr')
usePackage('ggplot2')
usePackage('scales')
usePackage('ggseas') # for stat_index
usePackage('grid')
usePackage('gridExtra')


# Download data from the Reserve Bank of New Zealand
download.file("http://www.rbnz.govt.nz/-/media/ReserveBank/Files/Statistics/Key%20graphs/graphdata.xlsx?la=en",
              destfile = "rbnz.xlsx", mode = "wb")

# Import some of that data into R and create a numeric TimePeriod variable from the original
# string that shows year and month:
forex <- read_excel("rbnz.xlsx", sheet = "8_NZDUSD", skip = 4) %>%
   mutate(year = as.numeric(substring(DATE, 1, 4)),
          month = as.numeric(substring(DATE, 6, 7)),
          TimePeriod = year + (month - 0.5) / 12) %>%
   select(-DATE, -year, -month)

# Tidy up names:
names(forex)[1:2] <- c("NZDUSD", "TWI")

# Create a long, thin ("tidy") version for use with ggplot2:
forex_m <- forex %>%  gather(variable, value, -TimePeriod) 

#------------dual axis version-------------
# As we're drawing a number of these, we want a function to make it easier.
# Here's one I prepared earlier:
source("https://gist.githubusercontent.com/ellisp/4002241def4e2b360189e58c3f461b4a/raw/9ab547bff18f73e783aaf30a7e4851c9a2f95b80/dualplot.R")     

# bad:
with(forex, dualplot(x1 = TimePeriod, y1 = NZDUSD, y2 = TWI, 
                     colgrid = "grey90", ylim2 = c(20, 200)))

# bad:
with(forex, dualplot(x1 = TimePeriod, y1 = NZDUSD, y2 = TWI, 
	colgrid = "grey90", ylim1 = c(0, 1)))

# verybad:
forex2 <- forex %>%
   mutate(NZDUSD_growth = c(NA, diff(NZDUSD)) / NZDUSD * 100)
with(forex2[-1, ], dualplot(x1 = TimePeriod, y1 = NZDUSD, y2 = NZDUSD_growth, 
	colgrid = "grey90", ylim2 = c(-15, 15)))   

# ok:
with(forex, dualplot(x1 = TimePeriod, y1 = NZDUSD, y2 = TWI, lwd = 1.2, colgrid = "grey90", 
                     main = "NZ dollar exchange rate & trade-weighted index",
                     ylab1 = "US dollars for one NZ dollar",
                     ylab2 = "Index",
                     yleg1 = "NZD / USD exchange rate (left axis)",
                     yleg2 = "Trade-weighted index (right axis)",
                     mar = c(5,6,3,6)))
mtext(side = 1, "Data from RBNZ; graphic by http://ellisp.github.io", 
	adj = 1, cex = 0.8, line = 3)

# ok again, equivalent to reference point for indexing of January 2014
with(forex, dualplot(x1 = TimePeriod, y1 = NZDUSD, y2 = TWI, lwd = 1.2, colgrid = "grey90", 
				 main = "NZ dollar exchange rate & trade-weighted index",
				 ylim.ref = c(361, 361), 
                 ylab1 = "US dollars for one NZ dollar",
				 ylab2 = "Index",
				 yleg1 = "NZD / USD exchange rate (left axis)",
				 yleg2 = "Trade-weighted index (right axis)",
				 mar = c(5,6,3,6)))
mtext(side = 1, "Data from RBNZ; graphic by http://ellisp.github.io", 
	adj = 1, cex = 0.8, line = 3)

#--------tidy up-----------
unlink("rbnz.xlsx")

The best chart from the above code is:

Dual Axes Chart