Вызовите функцию много раз, не дублируя ее (с%>%) - PullRequest
0 голосов
/ 03 октября 2018

Давайте предположим, что у нас есть 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 ]

0 голосов
/ 06 октября 2018

Использование комбо partial / compose / invoke:

library(tidyverse)
f2b <- invoke(compose, map(c(F,T), ~substitute(partial(func2, plus =.), lst(.))))

func1(0) %>% f2b %>% func3
# [1] 1
0 голосов
/ 03 октября 2018

Напишите функцию, которая принимает начальные 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.Но я предполагаю, что у вас действительно есть функции, которые делают что-то более сложное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...