web-dev-qa-db-ja.com

Rでの省略記号の引数リストの解凍

一部の関数で省略記号(_..._)を使用すること、つまり、引数を含むオブジェクトを単一の引数として渡す方法に混乱しています。

Pythonでは、「引数リストの解凍」と呼ばれます。例:.

_>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # call with arguments unpacked from a list
[3, 4, 5]
_

たとえばRには、省略記号を使用する関数file.path(...)があります。私はこの振る舞いをしたいと思います:

_> args <- c('baz', 'foob') 
> file.path('/foo/bar/', args)
[1] 'foo/bar/baz/foob'
_

代わりに、私は

_[1] 'foo/bar/baz' 'foo/bar/foob'
_

ここで、argsの要素は「解凍」されず、同時に評価されません。 Python _*arg_に相当するRはありますか?

43
mhermans

構文はそれほど美しくはありませんが、これでうまくいきます。

do.call(file.path,as.list(c("/foo/bar",args)))

do.callは、関数とその関数を呼び出すための引数のリストの2つの引数を取ります。

関数内でlist(...)を呼び出すことにより、省略記号から情報を抽出できます。この場合、省略記号の情報はリストオブジェクトとしてパッケージ化されます。例えば:

> foo <- function(x,...){
+   print(list(...))
+ }
> foo(1:10,bar = 'bar','foobar')
$bar
[1] "bar"

[[2]]
[1] "foobar"

file.pathを呼び出すことで、do.callのようなベクトル化された関数から目的の動作を実現できます。これは、ラッパーsplatplyrパッケージ内)で使用する方が簡単な場合があります。 )

> args <- c('baz', 'foob')
> library(plyr)
> splat(file.path)(c('/foo/bar', args))
[1] "/foo/bar/baz/foob"
21
nullglob

それを見つけるのに少し時間がかかりましたが、 purrr パッケージには plyr::splat と同等のものがあります:それは lift_dl

名前の「dl」は、関数のドメインをある種類の入力から別の種類に「持ち上げる」ために使用できる一連のlift_xy関数の一部であるため、「dotstolist」を表します。これらの「種類」は、リスト、ベクトル、および「ドット」です。

lift_dlがおそらくそれらの中で最も有用であるため、単純なliftエイリアスが提供されています。

上記の例を再利用するには:

> library(purrr)
> args <- c('baz', 'foob')
> lift(file.path)(c('/foo/bar', args))
[1] "/foo/bar/baz/foob"
2
Nicolas Payette