R: Using output from one function to set all attributes of another function

Viewed 32

I want the output of one function to be able to set all, or possibly only the needed/given, attributes of another. I want to use the output of myFunction1() on its own, which does some calculations and based on that produces multiple needed values, or in combination with myFunction2(), which is supposed to use those values in a plot or similar. The code would look something like this:

myFunction1() >%> myFunction2()

I'm aware that I can possibly put the function that needs the output inside the first function, like:

myFunction1=function(x, logical){
 x=x^2
 y=""
if(x>100){
 y="hello"
}else{
 y="goodbye"
 }
if(logical){
 return(list(x=x,y=y,logical=logical))
}else{
 return(myFunction2(x,y,logical))
 }
} ##end myFunction1()

myFunction2=function(x, y, z){
a=paste0(x, y, z)
return(a)
}

or use the output with the $-operator

myOutput = myFunction(1, TRUE)
myOutput2 = myFunction2(myOutput$x, myOutput$y, myOutput$logical)

But is there a way to have a list output (or anything that can contain different data types) be able to set all attributes without the need of addressing the output via $ or index?

(First post so feedback regarding the wrongs would be appreciated aswell)

1 Answers

If the question is asking how to create a pipeline from myFunction1 and myFunction2 assuming we can modify myFunction1 but not myFunction2 then remove the test from myFunction1 and put it into the pipeline as shown.

myFunction1 <- function(x, logical) {
  y <- if (x^2 > 100) "hello" else "goodbye"
  list(x = x, y = y, logical = logical)
}

myFunction2 <- function(x, y, z) {
  paste0(x, y, z)
}

# tests - 3 alternatives

library(magrittr)

# 1 - with
myFunction1(1, TRUE) %>%
  with(if (logical) myFunction2(x, y, logical) else .)
## [1] "1goodbyeTRUE"

# 2 - magrittr %$%
myFunction1(1, TRUE) %$%
  if (logical) myFunction2(x, y, logical) else .
## [1] "1goodbyeTRUE"

# 3 - do.call
myFunction1(1, TRUE) %>%
  { if (.$logical) do.call("myFunction2", unname(.)) else . }
## [1] "1goodbyeTRUE"

If we can modify both we could have myFunction2 accept a list.

myFunction2 <- function(List) {
  if (List$logical) do.call("paste0", List) else List
}
myFunction1(1, TRUE) %>% myFunction2
## [1] "1goodbyeTRUE"
Related