3

I want to compute the integral of a function associated with each value in a vector. Using an example, I precisely describe my aim as follows.

Suppose x and y are independent random variables, and I is an indicator variables such that I=1 if y > 0.25x or zero otherwise. I want to make n draws of y from an exponential distribution, and for each draw I wish to compute the integral of g = xf(x)I over the distribution of x, f(x). I want this distribution to be exponential with parameter value of 1. I tried the following code in r.

f = function(n){
  h = list()
  g = numeric()
  y = rexp(n)
  for(i in 1:n){
    h[i] = function(x){(x * dexp(x) * (y[i] > 0.5*x))}
    g[i] = integrate(h[i], lower=-Inf, upper=Inf)
  }
  return(summary(g))
}

But then when I run f(3) I get an error message "*Error in h[i] = function(x) { : cannot coerce type 'closure' to vector of type 'list'"*. But when I run the following codes

y = rexp(1)
h = function(x){x * dexp(x) * (y > 0.5*x)}
integrate(h, lower=-Inf, upper=Inf)
f(3)

I get results. Does somebody has suggestion on how to improve this code so that h function is evaluated at each values of y with the output being a function, which then will be passed to the g function?

1
  • 1
    Try using [[ to index your list rather than [, ie h[[i]] Commented Nov 11, 2013 at 11:55

2 Answers 2

1

I would suggest to use sapply instead of the loop:

f = function(n){
  y = rexp(n)
  g = sapply(1:n, function(i) 
                  integrate(function(x) (x * dexp(x) * (y[i] > 0.5*x)), lower=-Inf, upper=Inf))
  return(summary(g))
}
Sign up to request clarification or add additional context in comments.

2 Comments

Why would you suggest using sapply - I'm not saying it's an incorrect suggestion, but a reason would be nice.
I used summary(g[1,]) to extract the value of the integral since g is a list. The use of sapply makes sense because it calls for a specified function (h in this case) for each element in a vector y.
1

You need to use [[ to subset h rather than [. This is because [ will return a sub-list rather than the contents. Also integrate returns a complex structure, if you just want the value, append with $value to pick that out.

f = function(n){
  h = list()
  g = numeric()
  y = rexp(n)
  for(i in 1:n){
    h[[i]] = function(x){(x * dexp(x) * (y[i] > 0.5*x))}
    g[i] = integrate(h[[i]], lower=-Inf, upper=Inf)$value
  }
  return(summary(g))
}

f(3)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.2456  0.3269  0.4082  0.4069  0.4876  0.5669 

1 Comment

This is exactly what I wanted to do. sapply also does a similar job as @Thilo suggests.

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.