mynameisJEFF
mynameisJEFF

Reputation: 4239

Issues using mapply

I am trying to create a contour plot, using the mapply function. I am a newbie to R, I have read other's post on mapply and I still dont get the essence of mapply function. I am stuck at the following problem.

I have a function px (which takes in 2 arguments ) that returns a value. And I am trying to make a contour plot using the draw.graph function, which will take in 2 sequences (n1,n2) as arguments. However, I kept getting an error, saying that the the z in contour() is not a matrix.

I tried to use browser() and realised that after performing mapply(), I didnt get a matrix. So my question is how can I get a matrix using mapply function in this context ??? And if possible, can someone point out the mistakes i have made in my code? I kept getting the following error:

 Error in contour.default(n1, n2, y) : no proper 'z' matrix specified

    # This function returns a value only    
        px <- function(mu.a, mu.b)
            {
                   #Note that x is just a vector in this context. specified
                   # outside the function. Since it is very long, I want specify it here.           
                    n1 <- dnorm(x, mean = mu.a, sd = 0.3)
                n2 <- dnorm(x, mean = mu.b, sd = 0.3)

                pxd<- 0.7 * n1 + (1-0.7) * n2

                return
                {
                    prod(pxd)
                }   
            } 
            #I am trying to generate a contour plot below of the function px.q3 with
           # arguments n1,n2, which will be sequences
            draw.graph <- function(n1,n2)
            {   

                y <- mapply(px,n1,n2)
                browser()
                contour(n1,n2,y)
            }
            draw.graph(seq(1.0,1.6,0.01),seq(2.4,3,0.01))

My aim of the draw.graph function is to get a contour plot as a function mu.a(i.e. n1) and mu.b(i.e. n2) <- 2 sequences. 

Upvotes: 0

Views: 485

Answers (2)

Stephen Henderson
Stephen Henderson

Reputation: 6522

Here instead of using mapply() you can use outer().. which instead of doing it piecewise does all combinations which is I think what you want? NB Note the use of Vectorize() to create a vectorised function that accepts mu.a and mu.b as vectors whilst x is fixed for all combinations.

This below definitely works (i.e. produces a working Fig) but I'm not sure it's supposed to look like that???

x1 = seq(0, 1,.1)
n1=seq(1.0,1.6,0.01)
n2=seq(2.4,3,0.01)

#question 3 - as a function mu.a, mu.b
px.q3 <- function(mu.a, mu.b, x=x1)
{
  n1 <- dnorm(x, mean = mu.a, sd = 0.3)
  n2 <- dnorm(x, mean = mu.b, sd = 0.3)
  #p(x_d)
  pxd<- 0.7 * n1 + (1-0.7) * n2

  return
  {
  prod(pxd)
  }   
}

vectorised.px.q3=Vectorize(px.q3)
y= outer(n1,n2, FUN=vectorised.px.q3)
contour(n1,n2,y)

Upvotes: 1

Stephen Henderson
Stephen Henderson

Reputation: 6522

You do not pass any value of x into this function...I assume you are using a global??? Naughty!

You can make px FUN like this

px <- function(mu.a, mu.b, x)
        { etc..

And you can then specify the x using the MoreArgs option

y2 <- mapply(FUN=px,n1,n2, MoreArgs=list(x), SIMPLIFY = T)

y2 is a vector not a matrix you need to reshape

dim(y2)=c(length(n2), length(n1))

Upvotes: 3

Related Questions