-2

I need to create plots that have 2 y axes, one that shows dollars (whose scale is in millions) and another metric (whose scale is much smaller (spanning from 10s to 100s). I have the below loop using sec_axis because i have many variables that I need to plot, but the secondary axis on the right hand side of the plot that is supposed to represent the metric is using the same scale as the dollar axis. Why is this ?

for (metric in metrics) {
  for (brand_name in unique(entire_brand_month_data$Brand)){
    brand_data <- entire_brand_month_data[entire_brand_month_data$Brand == brand_name,]
    ggplot(brand_data, aes(x=Date)) +
      geom_line(aes(y=total_dollars, color = "Dollar Sales")) +
      geom_line(aes(y=get(metric), color = metric)) +
      scale_y_continuous(
        sec.axis = sec_axis(trans = ~., name = metric)
      ) +
      labs(title = paste("Brand", brand_name, "Sales and", metrics),
           x="Date",
           y="Dollar Sales") +
      theme_minimal() + guides(guide_legend(title = "Legend"))->p
    print(p)
  }
}
statquest
  • 1
  • 2
  • 4
    It's the same because you used `trans = ~ .`, which is effectively the identity function. See https://stackoverflow.com/q/46672694/3358272, https://stackoverflow.com/q/10183888/3358272, https://stackoverflow.com/q/3099219/3358272 for discussions on `sec_axis`. Bottom line: all data _must_ be in the scale of the primary axis, so you need to convert your second-axis points to the primary scale, and then tell ggplot how to convert it to the second scale. – r2evans Aug 14 '23 at 22:05
  • 4
    BTW, you're much less likely to get any help without sample data, see https://stackoverflow.com/q/5963269 , [mcve], and https://stackoverflow.com/tags/r/info for discussions on reproducibility. Thanks! – r2evans Aug 14 '23 at 22:06
  • ok but since i have 8 different metrics, how can i create a scaling factor in my loop for the secondary y axis that is unique to each metric? – statquest Aug 14 '23 at 22:09
  • *aside*: when looping over variables, or rather: levels of a variable (like a set of metrics), `facet_wrap` and `facet_grid` of {ggplot2} come in really handy. – I_O Aug 14 '23 at 22:11
  • 2
    I don't know for sure since I don't know your data, but all you need is a slope and an intercept, and then reverse it. If you don't want to share your data, perhaps shift your question to use a public dataset such as `mtcars` or `dplyr::starwars` or `ggplot2::diamonds`. – r2evans Aug 14 '23 at 22:29
  • "how can i create a scaling factor in my loop for the secondary y axis that is unique to each metric?" I'm not sure I follow -- does this imply you want the same scale of primary axis for each metric? – Jon Spring Aug 14 '23 at 23:33

1 Answers1

0

You could do something like this in your loop:

    ...
    m <- lm(reformulate(metric, response="total_dollars"), data=brand_data)
    b <- coef(m)[2]
    a <- coef(m)[1]
    ggplot(brand_data, aes(x=Date)) +
      geom_line(aes(y=total_dollars, color = "Dollar Sales")) +
      geom_line(aes(y=a + b*get(metric), color = metric)) +
      scale_y_continuous(
        sec.axis = sec_axis(trans = ~(.-a)/b, name = metric)
      )...

This uses a linear model to put metric on the same scale as total_dollars and then unwinds the transformation in sec.axis. It may not be perfect, but it will be a good start.

DaveArmstrong
  • 18,377
  • 2
  • 13
  • 25