Skip to contents

The purpose of this function is to construct a secondary axis with a projection function.


  data = NULL,
  primary = c(0, 1),
  secondary = c(0, 1),
  method = c("range", "max", "fit", "ccf", "sortfit"),
  na.rm = TRUE,



A data.frame object.

primary, secondary

An expression that is evaluated in the context of the data argument. These can be symbols for column names or plain expressions.


One of the following:


Causes the ranges of primary and secondary data to overlap completely.


Causes the maxima of primary and secondary data to coincide.


Uses the coefficients of lm(primary ~ secondary) to make the axes fit.


Uses the lag at which maximum cross-correlation occurs to then align the data by truncation. The aligned data is then passed to the "fit" method.


Sorts the both primary and secondary independently before passing these on to the "fit" method.


A logical(1): whether to remove missing values (TRUE) or propagate missing values (FALSE). Applies to the method = "range" and method = "max" methods.


Arguments passed on to ggplot2::sec_axis


A formula or function of a strictly monotonic transformation


The name of the secondary axis


One of:

  • NULL for no breaks

  • waiver() for the default breaks computed by the transformation object

  • A numeric vector of positions

  • A function that takes the limits as input and returns breaks as output


One of:

  • NULL for no labels

  • waiver() for the default labels computed by the transformation object

  • A character vector giving labels (must be same length as breaks)

  • A function that takes the breaks as input and returns labels as output


A position guide that will be used to render the axis on the plot. Usually this is guide_axis().


An AxisSecondary ggproto object with a proj method for projecting secondary data.


The intent is to run this function before starting a plot. The output of the function is a secondary axis wherein the trans argument of sec_axis() is populated by an appropriate transformation. In addition, the output also contains a output$proj() function that helps transform the secondary data.


# Run the secondary axis helper
sec <- help_secondary(economics, primary = unemploy, secondary = psavert)

# Making primary plot
p <- ggplot(economics, aes(date)) +
  geom_line(aes(y = unemploy), colour = "blue")

# For the secondary data, later we use the `proj` function from the helper
p <- p + geom_line(aes(y = sec$proj(psavert)), colour = "red")

# We feed the scale the secondary axis
p + scale_y_continuous(sec.axis = sec)

# Setup cross-correlated data
n <- 100
lag <- 20
dat <- cumsum(rnorm(n + lag))
df <- data.frame(
  x = seq_len(n),
  y1 = head(dat, n),
  y2 = 10 + tail(dat, n) * 5 # offset and scale y2
# Choosing the cross-correlation function method.
sec <- help_secondary(df, y1, y2, method = "ccf")

ggplot(df, aes(x)) +
  geom_line(aes(y = y1), colour = "blue") +
  geom_line(aes(y = sec$proj(y2)), colour = "red") +
  scale_y_continuous(sec.axis = sec)