Domanda

Sono confuso con l'uso del ellissi (...) in alcune funzioni, cioè come passare un oggetto contenente gli argomenti come argomenti.

In Python si chiama "spacchettamento liste di argomenti", per es.

>>> 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 per esempio si ha la funzione di file.path(...) che utilizza i puntini di sospensione. Mi piacerebbe avere questo comportamento:

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

Invece, ottengo

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

dove gli elementi della args non sono "spacchettato" e valutate allo stesso tempo. Esiste un equivalente a R Pythons *arg?

È stato utile?

Soluzione

La sintassi non è bello, ma questo fa il trucco:

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

do.call prende due argomenti: una funzione e un elenco di argomenti per chiamare tale funzione con.

Altri suggerimenti

È possibile estrarre informazioni dal puntini di sospensione chiamando list(...) all'interno della funzione. In questo caso, le informazioni nella puntini di sospensione è confezionato come un oggetto lista. Ad esempio:

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

[[2]]
[1] "foobar"

È possibile ottenere il comportamento desiderato dalle funzioni Vectorised come file.path con una chiamata a do.call, che a volte è più semplice da utilizzare con il splat involucro (nel pacchetto plyr)

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

Ci ho messo un po 'a trovarlo, ma il href="https://purrr.tidyverse.org/" rel="nofollow noreferrer"> purrr pacchetto ha un equivalente a plyr::splat : si chiama lift_dl .

Il "dl" nel nome sta per "punti a lista", in quanto è parte di una serie di funzioni lift_xy che possono essere utilizzati per "sollevare" il dominio di una funzione da un tipo di input per un altro tipo, questi "tipi" essere liste, vettori e "punti".

Dal lift_dl è probabilmente il più utile di questi, v'è un semplice alias lift prevista per esso.

Per riutilizzare l'esempio precedente:

> library(purrr)
> args <- c('baz', 'foob')
> lift(file.path)(c('/foo/bar', args))
[1] "/foo/bar/baz/foob"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top