I would like to label the x-axis with two non-linearly but monotonically related values. One is a decile and the other is a mean within the decile. Since there is no algebraic transformation between the two, I though I might use a vector but ggplot gives me an error message that the transformation must be monotonic. How is it checking and is there way to do what I trying?
df <-
data.frame(x = rnorm(500)) %>%
mutate(y = 1 + 2 * x) %>%
arrange(x) %>%
mutate(decile = ceiling(10 * 1:500 / 500)) %>%
group_by(decile) %>%
summarize(x = mean(x), y = mean(y))
sec_axis_label = df$x
df %>%
ggplot(aes(decile, y)) +
scale_x_continuous(expand = c(0, 0),
sec.axis = sec_axis(~ sec_axis_label[.])) +
geom_point()
The sec_axis
requires a transformation (formula), not a lookup. To see what's going on, I'll change it as follows:
sec_axis_label <- function(z) { browser() ; 1 ; }
df %>%
ggplot(aes(decile, y)) +
scale_x_continuous(expand = c(0, 0),
sec.axis = sec_axis(~ sec_axis_label(.))) +
geom_point()
We can explore and see what's going on:
# Browse[2]>
str(z)
# num [1:1000] 1 1.01 1.02 1.03 1.04 ...
# Browse[2]>
range(z)
# [1] 1 10
# Browse[2]>
Q
It's giving you enough potential values so that the transformation will return a meaningful range of other-axis-values so that it determine the best pretty-numbers.
So we need a transformation of sorts. If we assume interpolation is safe (I don't know if it is safe for you), we can do:
sec_axis_label <- function(a) approx(df$decile, df$x, xout=a)$y
df %>%
ggplot(aes(decile, y)) +
scale_x_continuous(expand = c(0, 0),
sec.axis = sec_axis(~ sec_axis_label(.))) +
geom_point()