Search code examples
rtidyversemagrittr

How to convert a function into pipe-friendly functions?


I'm trying to convert the following function into a pipe-friendly function. But it is made up of strings. I'm not sure where to begin.

library(MplusAutomation)

pathmodel <- mplusObject(
   TITLE = "MplusAutomation Example - Path Model;",
   MODEL = "
     mpg ON hp;
     wt by disp drat;",
   OUTPUT = "CINTERVAL;",
   rdata = mtcars)

I've tried this format, but I'm not sure which does not work and I'm not sure how to create this so that it works with pipes.

mplus <- function(data, title, on, by, output) {
  mplusObject(TITLE = as.character(title),
              MODEL = paste(on, "/n", by),
              OUTPUT = as.character(output),
              rdata = data)
  
}

This is what I'm trying to achieve by the end.

mplus %>%
  data(mtcars) %>%
  title("example - path model") %>%
  predictors("mpg on hp") %>%
  latentvars("wt by disp drat") %>%
  output(cinterval)

Solution

  • If you want to have pipable function, then you would need a pipeble object. Here we just stote the values in the a list. Something like

    new_mplus <- function(data=NA) {
      x <- list(TITLE=NA, MODEL=NA, OUTPUT=NA, predictors=NA, latent=NA, rdata=data)
      class(x) <- "mplus"
      x
    }
    
    is_mplus <- function(x) {
      "mplus" %in% class(x)
    }
    
    mplus <- function(data) {
      stopifnot(is.data.frame(data))
      new_mplus(data)
    }
    
    title <- function(x, title) {
      stopifnot(is_mplus(x))
      x$TITLE <- title
      x
    }
    
    predictors <- function(x, predictors) {
      stopifnot(is_mplus(x))
      x$predictors <- predictors
      x
    }
    
    latentvars <- function(x, latent) {
      stopifnot(is_mplus(x))
      x$latent <- latent
      x
    }
    
    output <- function(x, output) {
      stopifnot(is_mplus(x))
      x$OUTOUT <- output
      x
    }
    
    

    And then you call it with

    mtcars %>%
      mplus() %>%
      title("example - path model") %>%
      predictors("mpg on hp") %>%
      latentvars("wt by disp drat") %>%
      output("cinterval")
    

    The list will keep track of all your values. Then you'd just need to have a function to execute it

    execute <- function(x) {
      mplusObject(TITLE = x$TITLE
                  MODEL = paste(x$predictors, "/n", x$latent),
                  OUTPUT = x$OUTPUT,
                  rdata = x$data)
    }
    
    mtcars %>%
      mplus() %>%
      title("example - path model") %>%
      predictors("mpg on hp") %>%
      latentvars("wt by disp drat") %>%
      output("cinterval") %>% 
      execute()
    

    Pipes are all about passing an object from one function to the next so you need some sort of object to pass that will store all the values. With dplyr you are passing around a tibble and with ggplot2 you are creating a ggplot object.