Теперь, когда invoke () устарел, какова альтернатива? - PullRequest
0 голосов
/ 14 марта 2020

rlang::invoke() теперь является устаревшим, purrr::invoke() удалено. В наши дни, каков аккуратный подход к программному вызову функции со списком аргументов?

1 Ответ

2 голосов
/ 14 марта 2020

tldr; Используйте exec вместо invoke; используйте map2 плюс exec вместо invoke_map.


Пример для invoke

С пенсионером invoke

set.seed(2020)
invoke(rnorm, list(mean = 1, sd = 2), n = 10)
#[1]  1.7539442  1.6030967 -1.1960463 -1.2608118 -4.5930686  2.4411470
#[7]  2.8782420  0.5412445  4.5182627  1.2347336

С exec

set.seed(2020)
exec(rnorm, n = 10, !!!list(mean = 1, sd = 2))
#[1]  1.7539442  1.6030967 -1.1960463 -1.2608118 -4.5930686  2.4411470
#[7]  2.8782420  0.5412445  4.5182627  1.2347336

Пример для invoke_map

Аналогично, вместо invoke_map вы бы использовали map2 с exec. Ранее вы использовали invoke_map для использования функции с различными наборами аргументов

set.seed(2020)
invoke_map(rnorm, list(list(mean = 0, sd = 1), list(mean = 1, sd = 1)), n = 10)
#    [[1]]
#     [1]  0.3769721  0.3015484 -1.0980232 -1.1304059 -2.7965343  0.7205735
#     [7]  0.9391210 -0.2293777  1.7591313  0.1173668
#
#    [[2]]
#     [1]  0.1468772  1.9092592  2.1963730  0.6284161  0.8767398  2.8000431
#     [7]  2.7039959 -2.0387646 -1.2889749  1.0583035

Теперь используйте map2 с exec

set.seed(2020)
map2(
    list(rnorm),
    list(list(mean = 0, sd = 1), list(mean = 1, sd = 1)),
    function(fn, args) exec(fn, n = 10, !!!args))
#    [[1]]
#     [1]  0.3769721  0.3015484 -1.0980232 -1.1304059 -2.7965343  0.7205735
#     [7]  0.9391210 -0.2293777  1.7591313  0.1173668
#
#    [[2]]
#     [1]  0.1468772  1.9092592  2.1963730  0.6284161  0.8767398  2.8000431
#     [7]  2.7039959 -2.0387646 -1.2889749  1.0583035

К сожалению, * Синтаксис 1038 * plus exec не такой лаконичный, как invoke_map, но, возможно, более канонический.

Несколько комментариев, которые могут помочь избежать проблем при использовании map2 плюс exec:

  1. Первый аргумент map2 должен быть list. Так что map2(list(rnorm), ...) будет работать. Просто предоставление функции как map2(rnorm, ...) не будет. Это отличается от invoke_map, который принимал как list функций, так и саму функцию.
  2. Второй аргумент должен быть list аргумента list с. map2 будет перебирать верхний уровень list, а затем использовать оператор большого взрыва !!! внутри exec для принудительного объединения list аргументов функции.
...