15

目標

dplyr を使用して、パラメーターのグリッドでシミュレーションを実行したいと考えています。具体的には、別のプログラムで使用できる機能が欲しい

  • data.frame が渡されます
  • 行ごとに、各列を引数として使用してシミュレーションを計算します
  • また、いくつかの追加データ (初期条件など) が渡されます。

これが私のアプローチです

require(dplyr)
run <- function(data, fun, fixed_parameters, ...) {
   ## ....
   ## argument checking
   ##

   fixed_parameters <- as.environment(fixed_parameters)
   grouped_out <- do_(rowwise(data), ~ do.call(fun, c(., fixed_parameters, ...)))
   ungroup(grouped_out)
 }

これは機能します。たとえば、

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

定義して実行できます

   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)

質問

これは機能しているように見えますが、 なしでそれを行う方法があるのだろうかdo.call. (一部には do.call の問題もあります。)

grouped_out <- do_(rowwise(data), ~ do.call(fun, c(., fixed_parameters, ...)))この行を、同じことを行うが なしの何かに置き換える方法に本当に興味がありdo.callます。編集:do.call上記のリンクで概説されている使用によるパフォーマンスの低下を何らかの形で回避するアプローチも機能します。

注意事項と参考文献

4

3 に答える 3

5

あなたのコードに従うのは少し難しいと思いましたが、これは同等だと思います。

最初に、興味のある計算を行う関数を定義します。

growth_t <- function(n0, r, K, b, T) {
  n <- n0

  for (t in 1:T) {
    n <- n + r - exp(n) / K - b - rnorm(1, 0, 0.1)
  }
  n
}

次に、担当者の「ダミー」変数を含め、変化させたいデータを定義します。

data <- expand.grid(
  b = seq(0.01, 0.5, length.out = 5),
  K = exp(seq(0.1, 5, length.out = 5)),
  r = seq(0.5, 3.5, length.out = 5),
  rep = 1:20
)

次に、それを にフィードできますpurrr::pmap_d()pmap_d()「並列」マップを実行します。つまり、リスト (またはデータ フレーム) を入力として取り、反復ごとにすべての名前付き引数を変更して関数を呼び出します。固定パラメーターは、関数名の後に指定されます。

library(purrr)
data$output <- pmap_dbl(data[1:3], growth_t, n0 = 0.9, T = 5)

これは、実際にはデータ操作に関するものではないため、dplyr の問題とは思えません。

于 2016-05-25T17:41:52.507 に答える
1

以下では、使用を避けdo.call、OP と同じ方法で出力を表示します。

まず、関数のパラメーターを、渡すベクターに置き換えます。これは、apply を使用して渡すものです。

growth_runner <- function(data.in, 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, data.in[3], data.in[2], data.in[1])
  };
    n0})
  )
}

以前と同じように、検索するグリッドを設定します。

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)

apply を使用してグリッドを通過し、結果を追加します

output.mid = apply(data, 1, ic=initial_data, FUN=growth_runner)
output <- data.frame('n_final'=unlist(output.mid))

また、外部ライブラリへの呼び出しや外部ライブラリなしで出力が得られますdo.call

> dim(output)
[1] 20000     1
> head(output)
     n_final
1 -0.6375070
2 -0.7617193
3 -0.3266347
4 -0.7921655
5 -0.5874983
6 -0.4083613
于 2016-05-20T01:03:55.223 に答える