1
votes

I am trying to create some ggplots automaticly. Here is my working code example for adding stat_functions:

require(ggplot2)

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()+
  stat_function(fun= function(x){1*x},lwd=1.25, colour = "navyblue") + 
  stat_function(fun= function(x){2*x},lwd=1.25, colour = "navyblue") + 
  stat_function(fun= function(x){3*-x},lwd=1.25, colour = "red")
p1

As you can see the stat_functions all use (nearly) the same function just with a different parameter. Here is what i have tried to write:

f <- function(plot,list){
  for (i in 1:length(list)){
    plot <- plot + stat_function(fun= function(x){x*list[i]})
  }
  return(plot)
}

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()

p2 <- f(p1,c(1,2,3))
p2

This however doesnt return 3 lines, but only one. Why?

2
OK, so what's your question? What problem have you run into? - dash2
I guess i have hidden the problem too far into the code, sry. Most of my ideas return an empty plot. I have commented as the last part of the code what happens when i execute it. I will edit my post to make it easier to see. Sorry for the inconvenience. - Pablowa
I notice that in custom2 you have a for loop which is overwriting plot several times. Did you mean to write plot <- plot + stat_function(...)? - dash2
I did indead, good find! Now it shows 1 or two lines (depending on what starting parameters i give) but never more than 2 (even if i would expect 3 with the example given). It doesnt show more than one red and one blue line, even if i give him more than 2 inputs. i will edid the code to show this improvment - Pablowa
... and in custom1, you create some stat_function objects, but they never get returned from the function, because they're within a for loop. Just add a return call in the appropriate place. - dash2

2 Answers

3
votes

Your question is a bit confusing, because the first plot actually contains some other variable bits, but in your function you have a single stat_summary call for only one variable element.

Anyways. Keep the ggplot main object separate and create a list of additional objects, very easy for example with lapply. Add this list to your main plot as usual.

Check also https://ggplot2-book.org/programming.html

library(ggplot2)
p <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x)) + theme_minimal()

ls_sumfun <- lapply(1:3, function(y){
  stat_function(fun= function(x){y*x}, lwd=1.25, colour = "navyblue")
}
)

p + ls_sumfun

Created on 2021-04-26 by the reprex package (v2.0.0)

0
votes

In R, you can pass functions as arguments. You can also return functions from functions. This might make your code simpler and cleaner.

Here's an example:

p1 <- ggplot(data.frame(x = c(-2.5, 7.5)), aes(x = x))

add_stat_fun <- function (ggp, f) {
  ggp + stat_function(fun = f) 
}

make_multiply_fun <- function (multiplier) {
  force(multiplier) # not sure if this is required...
  f <- function (x) {multiplier * x}
  return(f)
}

my_funs <- lapply(1:3, make_multiply_fun)
# my_funs is now a list of functions

add_stat_fun(p1, my_funs[[1]])
add_stat_fun(p1, my_funs[[2]])
add_stat_fun(p1, my_funs[[3]])