Site icon R-bloggers

“If You Were an R Function, What Function Would You Be?”

[This article was first published on R – Win-Vector Blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

We’ve been getting some good uptake on our piping in R article announcement.

The article is necessarily a bit technical. But one of its key points comes from the observation that piping into names is a special opportunity to give general objects the following personality quiz: “If you were an R function, what function would you be?”

So our question is: can we add a meaningful association between the two deepest concepts in R objects (or references to them) and functions?

We think the answer is a resounding “yes!”

The following example (adapted from the paper) should help illustrate the idea.

Suppose we had simple linear model.

set.seed(2019)
data_use <- base::sample(c("train", "test"), 
   nrow(mtcars), replace = TRUE)
mtcars_train <- mtcars[data_use == "train", , drop = FALSE]
mtcars_test <- mtcars[data_use == "test", , drop = FALSE]
model <- lm(mpg ~ disp  + wt, data = mtcars_train)

Now if “model” were an R function, what function would it be? One possible answer is: it would be predict.lm(). It would be nice if “model(mtcars_test)” meant “predict(model, data = mtcars_test)“. Or, if we accept the pipe notation “mtcars_test %.>% model” as an approximate substitute for (note: not an equivalent of) “model(mtcars_test)” we can make that happen.

The “%.>%” is the wrapr dot arrow pipe. It can be made to ask the question “If you were an R function, what function would you be?” as follows.

First a bit of preparation, we tell < cod>R‘s S3 class system how to answer the question.

apply_right.lm <-
  function(pipe_left_arg,
           pipe_right_arg,
           pipe_environment,
           left_arg_name,
           pipe_string,
           right_arg_name) {
    predict(pipe_right_arg,
            newdata = pipe_left_arg)
  }

And now we can treat any reference to an object of class “lm” as a pipe destination or function.

mtcars_test %.>% model

And we see our results.

#          Mazda RX4       Mazda RX4 Wag      Hornet 4 Drive          Duster 360            Merc 280 
#          23.606199           22.518582           20.477232           18.347774           20.062914 
#          Merc 280C          Merc 450SE  Cadillac Fleetwood Lincoln Continental            Fiat 128 
#          20.062914           16.723133           10.506642            9.836894           25.888019 
#   Dodge Challenger         AMC Javelin       Porsche 914-2        Lotus Europa      Ford Pantera L 
#          18.814401           19.261396           25.892974           28.719255           20.108134 
#      Maserati Bora 
#          18.703696 

Notice we didn’t have to alter model or wrap it in a function. This solution can be used again and again in many different circumstances.

To leave a comment for the author, please follow the link and comment on their blog: R – Win-Vector Blog.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.