web-dev-qa-db-ja.com

R purrr ::: pmap:入力引数を名前で参照する方法は?

3つの入力でR purrr:::pmapを使用しています。 formula呼び出しでこれらの入力を明示的に参照する方法が明確ではありませんか? map2を使用する場合、formula呼び出しは~ .x + .yとして実行されます。しかし、pmapを使用する場合の方法は?

http://r4ds.had.co.nz/lists.html からのHadleyの例の再現

library(purrr)
mu <- list(5, 10, -3)
sigma <- list(1, 5, 10)
n <- list(1, 3, 5)

args2 <- list(mean = mu, sd = sigma, n = n)
pmap(args2, rnorm)

rnormを呼び出すときに入力引数を明示的に参照する場合は、次のように使用できます。

pmap(args2, function(mean, sd, n) rnorm(n, mean, sd))

しかし、formulaアプローチでこれを実行したいとします。それ、どうやったら出来るの?たとえば、これは機能しません。

pmap(args2, ~rnorm(n=.n, mean=.mean, sd=.sd))

ありがとう!!

17
Matifou

これを解決するには、with(...)を使用できます。

pmap(args2, ~with(list(...),rnorm(n, mean, sd)))
# [[1]]
# [1] 2.733528
# 
# [[2]]
# [1] 4.0967533 6.4926143 0.6083532
# 
# [[3]]
# [1]  1.8836592 -0.2090425 -4.0030168  1.1834931  3.2771316

詳細な説明はこちら: purr :: pmapで.fリスト名を利用する

7

バージョン0.2. なので、_..1_、_..2_、_..3_などを使用できます。

_pmap(args2, ~ rnorm(..3, ..1, ..2))
_

しかし...私はすでにこの構文で問題に遭遇しました、例えばreplicate

_pmap(list(1, 2), ~ replicate(n = ..1, expr = ..2))
# Error in FUN(X[[i]], ...) : the ... list does not contain 2 elements
_

おそらく次の理由により:

_print(replicate)
# function (n, expr, simplify = "array") 
#   sapply(integer(n), eval.parent(substitute(function(...) expr)), 
#          simplify = simplify)
_

function(...) exprsubstitute()は_..2_でうまく機能せず、空の_..._の2番目の要素として解釈されるようです。

pmap(list(1, 2), ~ replicate(n = ..1, expr = .y))は引き続き機能することに注意してください。

11
Aurèle

pmapは、式インターフェースのリストの名前では引数にアクセスできないようです。 https://github.com/hadley/purrr/issues/2 でチェックインできます。

たとえば、次のことができます。

_pmap(list(1:2, 5:6), ~ .x + .y)
_

したがって、リストの最初の要素は_.x_によって参照され、2番目の要素は_.y_によって参照されます。ただし、次のようにリストの引数に名前を付けようとすると、

_pmap(list(a = 1:2, b =  5:6), ~ .a + .b)
_

次にエラーが発生します:

_Error in .f(a = .l[[c(1L, i)]], b = .l[[c(2L, i)]], ...) : 
  unused arguments (a = .l[[c(1, i)]], b = .l[[c(2, i)]])
_

関数pmapの数式インターフェイスで、数式インターフェイスを使用してfunction(mean , sd, n)を使用しない場合にできる最善の方法は次のとおりです。

  1. リストの要素に名前を付けない
  2. 3つ以上の引数を使用しない(暗黙の名前_.x_および_.y_を使用するため)

したがって、使用して、必要な3番目の引数n(たとえば、_n = 4_)の値を修正し、実行できます。

_mu <- list(5, 10, -3)
sigma <- list(1, 5, 10)
set.seed(1)
pmap(list(mu,sigma), ~ rnorm(mean = .x, sd = .y, n = 4))
_

どちらが返されますか:

_[[1]]
[1] 4.373546 5.183643 4.164371 6.595281

[[2]]
[1] 11.647539  5.897658 12.437145 13.691624

[[3]]
[1]  2.7578135 -6.0538839 12.1178117  0.8984324

[[4]]
[1]  9.136278  4.355900 14.374793 10.865199
_
4