Duna
Duna

Reputation: 735

For loop over a function to get function output in R

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?

Upvotes: 3

Views: 1074

Answers (2)

James
James

Reputation: 66834

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 

Upvotes: 1

Thilo
Thilo

Reputation: 9157

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))
}

Upvotes: 1

Related Questions