简体   繁体   中英

ggplot2 plot function with several arguments

I got this function.

change <- function(score, d, k, p) {k*(score - 1/(1+k^(d/p)))}

I would like to plot, in one single plot, all results of this function for a range of arguments d and p. In base r it would be this.

parameters <- c(100:400)
colorshelf <-rainbow(length(parameters)) #red is low
for(i in seq_along(parameters)) {
    print(i)
    curve(change(score=1, d=x, k=100, p=parameters[i]), from=0, to=500, add=T, col=colorshelf[i])
}

But I thought this must be possible in ggplot2, but can not wrap my head around this. I am currently stuck with this. Any help is appreciated.

ggp <- ggplot(data.frame(Ds=c(0:1000), Ps=c(0:1000)), aes(x=Ds, col=Ps)) + 
    stat_function(fun=change, args=list(score=1, d=Ds, k=100, p=Ps))
ggp

I would do this outside of ggplot2 . I think it might be too much to expect ggplot to vectorise over two different parameters ...

This is with tidyverse, but could easily be done with apply as well.

 library(dplyr)
 change <- function(score, d, k, p) {k*(score - 1/(1+k^(d/p)))}
 dd <- expand.grid(d=0:1000,p=0:100)
 dd %>% rowwise %>%
     mutate(c=change(score=1,d=d,k=100,p=p)) ->
  dd2

 library(ggplot2)
 ggp <- ggplot(dd2,aes(d,c,col=p,group=p))+
            geom_path()

I only did p from 0 to 100 (rather than 0 to 1000) because 1 million points is a fairly large data set for ggplot. (Do you really need to see 1000 separate values? Maybe seq(0,1000,length=100) ?

just now, i had a very similar problem; i wanted to plot a function in ggplot with multiple parameters stored rowwise in a dataframe. As i did not need the dataframe with the function evaluated for each data point in the remainder of my code, i let ggplot do the dirty work for me. However, my approach comes at the minor disadvantage of positional knowlege on the dataframes ordering in apply (which should not be your problem). Also i need a color column (here: 'group'), which was in my case actually desirable for grouping. And ever since your parameters are unbalnced, you will have to expand.grid the parameters

The skeleton of the solution i came up with is basically the following:

p = ggplot(data.frame(x = c(-5, 10)), aes(x)) 
# this format specifies start & end of the x-axis for which the function is evaluated. 
d = data.frame(mu = 1:4, sigma= c(1,1,2,2), group = c(1,1,2,2))
# each row is a parameter set.
p = p + apply(
  d,
  MARGIN = 1,
  FUN = function(z)
    stat_function(
      fun = dnorm, # you can specify your own function which lives in .GlobalEnvir
      geom = "line",
      args = list(mean = z[1] , sd = z[2]),
      color = z[3]
    )
)
print(p)

But if you would have a non-standardized set of parameters (eg sometimes you dont have values for mean or sd and would want to omit them entirely in the passing of args) a more flexible approach with lapply might be an alternative. Note, that if you would like to use a default value of the function eg dnorm, you do not need to specify the particular parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM