Вызовите функцию много раз, не дублируя ее (с%>%)
Давайте предположим, что у нас есть 3 функции с этой минимальной функциональностью:
func1 <- function (x) {
x + 1
}
func2 <- function (x, plus = T) {
if (plus == TRUE) {
x + 2
} else {
x - 5
}
}
func3 <- function (x) {
x + 3
}
Я хотел бы вложить эту функцию друг в друга, как это с оператором трубы (%>%):
library(magrittr)
func1(0) %>% func2(plus = T) %>% func2(plus = F) %>% func3
# result: 1
Какая эквивалентная версия этого:
func3(func2(func2(func1(0), plus = T), plus = F))
# result: 1
Я пытаюсь найти метод, который не требует дублирования функции func2() (потому что мне приходится многократно запускать ее, а также я хотел бы динамически изменять количество вызовов функции и параметра). В настоящее время я не большой специалист по прикладным функциям или пакетам карт, но я думаю, что по крайней мере один из них может сделать эту работу.
Это, конечно, просто пример, мой реальный код намного сложнее, я просто пытаюсь упростить мою проблему, чтобы найти решение.
Мне приходится пользоваться оператором трубопровода, поэтому меня интересуют только те решения, которые также работают с трубами.
2 ответа
Напишите функцию, которая принимает начальный x
и результаты, чтобы накормить func2
и проходит через эти результаты:
func2_iterate = function(x, outcomes){
for (i in 1:length(outcomes)){
x = func2(x, outcomes[i])
}
return(x)
}
Тогда беги (с func1
, func2
, func3
как указано выше):
func1(0) %>% func2_iterate(c(T, F)) %>% func3
#result: 1
Я также хотел бы отметить, что в данном конкретном случае выход func2_iterate
это просто вход, плюс 2
раз количество T
в outcomes
минус 5
раз количество F
в outcomes
, Но я предполагаю, что у вас действительно есть функции, которые делают что-то более сложное.
Используя partial
/ compose
/ invoke
комбо:
library(tidyverse)
f2b <- invoke(compose, map(c(F,T), ~substitute(partial(func2, plus =.), lst(.))))
func1(0) %>% f2b %>% func3
# [1] 1