0

I am trying to plot a density function for various values of two parameters as follows:

f_bdsn<-function(x){
  2*(1+delta1*x^2)*dnorm(x)*pnorm(alpha1*x)/(1+delta1)
  }
alpha1<<-0
alpha1<<-0
group1=paste("alpha=",alpha1,", delta=",delta1)
p9 <- ggplot(data.frame(x = c(-4, 4)), aes(x = x)) +
  stat_function(fun = f_bdsn, aes(colour = group1)) 
alpha1<<-0
delta1<<-6
group2=paste("alpha=",alpha1,", delta=",delta1)
p9 <-p9 + stat_function(fun = f_bdsn,
                    aes(colour = group2)) 
p9

I am confused why it does not work! It only draws the function for last values of the parameters.

2 Answers 2

2

I've had to make some changes to your original function. Basically, the alpha and delta values need to be parameterised and passed into when calling the function. Then using a for loop we can create as many groups as we want.

# Create Function which takes in an x value, a delta value and an alpha value
f_bdsn<-function(x, delta_input, alpha_input){
  2*(1+delta_input*x^2)*dnorm(x)*pnorm(alpha_input*x)/(1+delta_input)
}

# Define the number of groups, alpha values and delta values
# Note the length of both alpha_values and delta_values are the same
n_groups <- 2
alpha_values <- c(0, 10)
delta_values <- c(6, 16)

# Create inital plot
plot <- ggplot(data.frame(x = c(-4, 4)), aes(x = x))

# Create a for loop to through each group
for (i in seq_len(n_groups)) {
  # Define the group name
  group_name <- paste("alpha=", alpha_values[i],", delta=", delta_values[i])
  
  # Add the values to the main plot variable
  plot <- plot + 
    stat_function(fun = f_bdsn, args = list(delta_input = delta_values[i],
                                            alpha_input = alpha_values[i]),
                  aes(colour = group_name))
}

# Print Plot
plot
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that the parameter values of ggplot for the most part are lazily evaulated. The values aren't actually evaluated until the plot is drawn. Since your function uses global variables, those values aren't resolved till plot time and at the time of the plot they will only have one value, not two different values. You can change this by creating a function generator. For example

f_gen <- function(alpha1, delta1) {
  force(c(alpha1, delta1))
  function(x){
    2*(1+delta1*x^2)*dnorm(x)*pnorm(alpha1*x)/(1+delta1)
}}
alpha1 <- 0
delta1 <- 0
group1 <- paste("alpha=",alpha1,", delta=",delta1)
p9 <- ggplot(data.frame(x = c(-4, 4)), aes(x = x)) +
  stat_function(fun = f_gen(alpha1,delta1), aes(colour = group1)) 
alpha1 <- 0
delta1 <- 6
group2 <- paste("alpha=",alpha1,", delta=",delta1)
p9 <- p9 + 
  stat_function(fun = f_gen(alpha1,delta1), aes(colour = group2)) 
p9

Here fgen is a function that returns a function with the parameters you desire. You might even simplify that to

f_gen <- function(alpha1, delta1) {
  force(c(alpha1, delta1))
  function(x){
    2*(1+delta1*x^2)*dnorm(x)*pnorm(alpha1*x)/(1+delta1)
  }}
gname <- function(alpha1, delta1) paste("alpha=",alpha1,", delta=",delta1)

ggplot(data.frame(x = c(-4, 4)), aes(x = x)) +
  stat_function(fun = f_gen(0,0), aes(colour = gname(0,0))) + 
  stat_function(fun = f_gen(0,6), aes(colour = gname(0,6))) +
  labs(color="Params")

1 Comment

How to change legend size(text size) in stat_function?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.