Есть ли R-эквивалент Python '*'? - PullRequest
3 голосов
/ 16 октября 2019

В python вы можете сделать:

val = [1, 2, 3]

def f(a, b, c):
    return(a+b+c)

f(*val)

>>>6

Но существует ли R-эквивалент для передачи списка / вектора в функцию и его распаковки списка / вектора в качестве аргументов функции?

val <- c(1, 2, 3)
f <- function(a, 
              b, 
              c) {
     a+b+c
     }
#f(*val)

Ответы [ 2 ]

9 голосов
/ 16 октября 2019

База R

do.call В R это do.call. Первый аргумент - это функция или символьная строка, дающая имя функции, а второй аргумент - список, компоненты которого будут переданы в качестве отдельных аргументов функции. Пакеты не используются.

val <- c(1, 2, 3)
f <- function(a, b, c) a+b+c
do.call("f", as.list(val))
## [1] 6

Reduce Другой подход заключается в карри f создании новой функции с фиксированным первым аргументом, неоднократно делая это, используя Reduce для обработки каждого последующегоаргумент. Пакеты не используются.

Reduce(function(f, x, ...) function(...) f(x, ...), val, init = f)()
## [1] 6

пакет purrr

invoke Пакет purrr имеет invoke, который в основном просто вызывает do.call, но он также преобразует второйаргумент для списка, если он еще не является списком:

library(purrr)
invoke(f, val)
## [1] 6

lift purrr также имеет lift, который преобразует функцию, которая принимает отдельные аргументы, в новую функцию, которая принимаетсписок или вектор. Он также переносит do.call

lift(f)(val)
## [1] 6

частичный purrr также имеет partial, который будет каррировать функцию, создавая новую функцию с фиксированным первым аргументом, принимая только оставшиеся аргументы, используя reduce (также в purrr) для многократного вызова такого каррирования:

reduce(val, partial, .init = f)()
## [1] 6

функциональный пакет

Curry Curry из функционального пакета также может быть использован для исправленияпервый аргумент. При использовании вместе с Reduce от базы R для многократного применения Curry это дает тот же результат. Обратите внимание, что Curry использует do.call для внутреннего использования.

library(functional)
Reduce(Curry, init = f, val)()
## [1] 6
2 голосов
/ 16 октября 2019

Другой вариант - поднять домен функции , используя lift() из пакета purrr. Ваше определение f принимает несколько аргументов, которые в терминах R известны как «точки». Вы можете изменить его подпись, чтобы принять вектор вместо:

f2 <- purrr::lift_dv(f)
f2(val)
## [1] 6

# Or as a one-liner
purrr::lift_dv(f)(val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...