0

Some data:

webdata <- data.frame(
  date = seq(as.Date("2021/1/1"), as.Date("2021/1/05"),by="day"),
  sessions = rnorm(5, 10000, 300),
  conversions = rnorm(5, 200, 50)
) %>% mutate(conversion_rate = conversions / sessions,
             mult = sessions / conversion_rate)

I can make a dual plot plot showing the trend of sessions and conversion rate like this:

webdata %>% ggplot(aes(date, sessions)) +
  geom_col(fill = 'steelblue') +
  geom_line(aes(date, (conversion_rate * (sessions / conversion_rate) * 1.2)), col = 'orange') + # make line just above columns
  scale_y_continuous(sec.axis = sec_axis(~. / 100000))

Looks like this: enter image description here

But I want the scale factor 100000 in scale_y_continuous(sec.axis = sec_axis(~. / 100000)) to be based on a column mult. This way the conversion rate is relative as opposed to a fixed arbitrary amount.

Tried:

webdata %>% ggplot(aes(date, sessions)) +
  geom_col(fill = 'steelblue') +
  geom_line(aes(date, (conversion_rate * (sessions / conversion_rate) * 1.2)), col = 'orange') + # make line just above columns
  scale_y_continuous(sec.axis = sec_axis(~. / mult))

Which gives:

Error in f(...) : object 'mult' not found

How can I use the field mult inside of sec_axis()?

Doug Fir
  • 19,971
  • 47
  • 169
  • 299
  • Are you trying to implement a non-monotonic transformation in your secondary axis? AFAIK, ggplot2 only accepts monotonic transforms in secondary axes. Note that the secondary axis does not actually perform a transformation on your data, it only affects the position of tickmarks and labels. How would you imagine the secondary axis looks like in this case? Most advice on secondary axes is gathered here: https://stackoverflow.com/q/3099219/11374827. – teunbrand Jun 22 '21 at 22:10
  • Hi @teunbrand what I'm trying to do is get conversion rate ploted on the right hand side. E.g. on 1/1/21 it would show whatever row 1 for conversion rate is (data were generated with rnorm). E.g. for me, 1/1/21 with the example data has a conversion rate of 0.015 and a sessions of 9889. The first data point on the plot, 1/1/21 would thus have a column on the left side for 9889 and the line plot, measured from the right side would be 0.015 (or 1.5%). Am I making sense? – Doug Fir Jun 22 '21 at 22:13
  • Right that makes sense as a data transformation, but not for how ggplot2 implements secondary axes, which is restricted to breaks, labels and titles and does not affect the data/layers in any way. As with many answers in the previously linked question, you would have to transform data yourself. – teunbrand Jun 22 '21 at 22:21
  • Hi @teunbrand I looked at the lengthy linked post. I still don't see a work around though. When you say 'you would have to transform the data yourself', OK, I don't mind making transformations but I'm unclear on what I need to do. Could you spell it out for me, perhaps as a answer? I'm more concerned about the end result than trying to mould ggplot to fit my data in it's current form - i.e. I'm happy to make transformations to webdata before passing to ggplot, I just don't see what I need to do first? – Doug Fir Jun 22 '21 at 22:24
  • I don't know exactly what your calculation should be, but I'm imagining simply adjusting the y-aesthetic of the line layer. For example: `geom_line(aes(date, mult * (conversion_rate * (sessions / conversion_rate) * 1.2)))` – teunbrand Jun 22 '21 at 23:09

1 Answers1

0

I believe you're getting this error because sec_axis() needs you to refer to a specific numeric value or object that holds a numeric value by which to transform your second axis. I tried running this, which allowed sec_axis() to take the mult argument, but still produced an error message.

webdata %>% ggplot(aes(date, sessions)) +
  geom_col(fill = 'steelblue') +
  geom_line(aes(date, (conversion_rate * (sessions / conversion_rate) * 1.2)), col = 'orange') + # make line just above columns
  scale_y_continuous(sec.axis = sec_axis(~. / (mult = c(1, 1000))))  
Error: transformation for secondary axes must be monotonic

I think you would have to map to a column that has that coefficient.

L. South
  • 141
  • 8