jeudi 31 mars 2016

Using standard evaluation and do_ to run simulations on a grid of parameters without do.call

Goals

I want to use dplyr to run simulations on grids of parameters. Specifically, I'd like a function that I can use in another program that

  • gets passed a data.frame
  • for every row calculates some simulation using each column as an argument
  • also is passed some extra data (e.g., initial conditions)

Here's my approach

require(dplyr)
require(lazyeval)

run <- function(data, fun, fixed_parameters, ...) {
  fixed_parameters <- as.environment(fixed_parameters)
  data %>%
    rowwise %>%
    do_(interp( ~ do.call(fun, c(., fixed_parameters, ...))))
}

This works. For example, for

growth <- function(n, r, K, b) {
  # some dynamical simulation
  # this is an obviously-inefficient way to do this ;)
  n  + r - exp(n) / K - b - rnorm(1, 0, 0.1)
}
growth_runner <- function(r, K, b, ic, ...) {
  # a wrapper to run the simulation with some fixed values
  n0 = ic$N0
  T = ic$T
  reps = ic$reps
  data.frame(n_final = replicate(reps, {for(t in 1:T) {
                                          n0 <- growth(n0, r, K, b)
                                        };
                                        n0})
  )
}

I can define and run,

   data <- expand.grid(b = seq(0.01, 0.5, length.out=10),
                       K = exp(seq(0.1, 5, length.out=10)),
                       r = seq(0.5, 3.5, length.out=10))
   initial_data = list(N0=0.9, T=5, reps=20)
   output <- run(data, growth_runner, initial_data)

Question

Even though this seems to work, I wonder if there's a way to do it without do.call.

Notes and References

Aucun commentaire:

Enregistrer un commentaire