2

If you read ggplot's stat_function help, you can see that :

stat_function understands the following aesthetics (required aesthetics are in bold):

  • group
  • y

But there is no example on how to use it.

In my case, I want to access the "group" aes inside a custom function. Here is my unfortunate try (which only plot one curve, not 1 per group):

df = data.frame(A=1:10, B=rep(seq(1,1.8,by=0.2), 2), 
                myGroup=c(rep("Group1", 5), rep("Group2", 5)))

log.test = function(x, data, ...) {
  y = log(data$A + x*data$B)
  return(y)
}

ggplot(df) + 
  xlim(0,50) + ylim(0,50) + 
  labs(x="time", y="Y", color="Group") +
  stat_function(aes(group=myGroup), fun=log.test, args=list(data=df))

Something odd is that I cannot get the debugger to work inside log.test, so I don't know which variable is available.

Note that this would work perfectly with geom_abline(aes(intercept=A,slope=B,color=myGroup)) instead of stat_function(...).

I may have a big misunderstanding here, but I cannot manage to find it.

Dan Chaltiel
  • 7,811
  • 5
  • 47
  • 92
  • Your function has access to `x` (and the whole of `df`). Indeed it has access to all values of `x` (from 0 to 50) at once. You are basically doing something like `log(df$A + seq(0, 50, 0.1) * df$B)`, and getting a warning for it. I'm a bit unclear about what you actually want to achieve here. How is ggplot supposed to know what the different rows in your data are referring to? (Leaving the grouping out of it for now.) – Axeman Oct 04 '18 at 10:42
  • @Axeman Please take a look at the `abline` example I just added. I would like to achieve the exact same, but with `log(Ax+B)` instead of `Ax+B`. – Dan Chaltiel Oct 04 '18 at 11:26
  • @DanChaltiel your problem is matrix multiplication. The dimensions that you have for A and B are not correct! – Shirin Yavari Oct 04 '18 at 22:22
  • @ShirinYavari indeed I am not very friendly with matrix multiplication. Moreover, this works fine with abline. If you master this better than me, could you correct my code maybe ? – Dan Chaltiel Oct 05 '18 at 09:17
  • @DanChaltiel posted my solution but I think you should switch to ax+b not a+bx! I used your original a+bx but look into it! – Shirin Yavari Oct 05 '18 at 16:36

1 Answers1

0

Try this:

df = data.frame(A=1:10, B=rep(seq(1,1.8,by=0.2), 2), 
                myGroup=c(rep("Group1", 5), rep("Group2", 5))) #you don't even need to define df here because you're passing all the arguments inside mapply 

log.test = function(x,A,B) {
  y = log(A + x*B)
  return(y)
}

ggplot(data.frame(x = c(0, 50)), aes(x)) + 
  mapply(function(A, B, myGroup) {
    stat_function(fun = log.test, args = list(A = A, B = B), col = myGroup)
  }, 
  # enter A, B, and colors here
  A = c(0, 10), 
  B=rep(seq(1,1.8,by=0.2), 2), 
  myGroup=c(rep("red", 5), rep("green", 5)))

enter image description here

Shirin Yavari
  • 626
  • 4
  • 6