EVOLUTION-MANAGER
Edit File: lift.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>R: Lift the domain of a function</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" type="text/css" href="R.css" /> </head><body> <table width="100%" summary="page for lift {purrr}"><tr><td>lift {purrr}</td><td style="text-align: right;">R Documentation</td></tr></table> <h2>Lift the domain of a function</h2> <h3>Description</h3> <p><code>lift_xy()</code> is a composition helper. It helps you compose functions by lifting their domain from a kind of input to another kind. The domain can be changed from and to a list (l), a vector (v) and dots (d). For example, <code>lift_ld(fun)</code> transforms a function taking a list to a function taking dots. </p> <h3>Usage</h3> <pre> lift(..f, ..., .unnamed = FALSE) lift_dl(..f, ..., .unnamed = FALSE) lift_dv(..f, ..., .unnamed = FALSE) lift_vl(..f, ..., .type) lift_vd(..f, ..., .type) lift_ld(..f, ...) lift_lv(..f, ...) </pre> <h3>Arguments</h3> <table summary="R argblock"> <tr valign="top"><td><code>..f</code></td> <td> <p>A function to lift.</p> </td></tr> <tr valign="top"><td><code>...</code></td> <td> <p>Default arguments for <code>..f</code>. These will be evaluated only once, when the lifting factory is called.</p> </td></tr> <tr valign="top"><td><code>.unnamed</code></td> <td> <p>If <code>TRUE</code>, <code>ld</code> or <code>lv</code> will not name the parameters in the lifted function signature. This prevents matching of arguments by name and match by position instead.</p> </td></tr> <tr valign="top"><td><code>.type</code></td> <td> <p>A vector mold or a string describing the type of the input vectors. The latter can be any of the types returned by <code><a href="../../base/html/typeof.html">typeof()</a></code>, or "numeric" as a shorthand for either "double" or "integer".</p> </td></tr> </table> <h3>Details</h3> <p>The most important of those helpers is probably <code>lift_dl()</code> because it allows you to transform a regular function to one that takes a list. This is often essential for composition with purrr functional tools. Since this is such a common function, <code>lift()</code> is provided as an alias for that operation. </p> <h3>Value</h3> <p>A function. </p> <h3>from ... to <code>list(...)</code> or <code>c(...)</code></h3> <p>Here dots should be taken here in a figurative way. The lifted functions does not need to take dots per se. The function is simply wrapped a function in <code><a href="../../base/html/do.call.html">do.call()</a></code>, so instead of taking multiple arguments, it takes a single named list or vector which will be interpreted as its arguments. This is particularly useful when you want to pass a row of a data frame or a list to a function and don't want to manually pull it apart in your function. </p> <h3>from <code>c(...)</code> to <code>list(...)</code> or <code>...</code></h3> <p>These factories allow a function taking a vector to take a list or dots instead. The lifted function internally transforms its inputs back to an atomic vector. purrr does not obey the usual R casting rules (e.g., <code>c(1, "2")</code> produces a character vector) and will produce an error if the types are not compatible. Additionally, you can enforce a particular vector type by supplying <code>.type</code>. </p> <h3>from list(...) to c(...) or ...</h3> <p><code>lift_ld()</code> turns a function that takes a list into a function that takes dots. <code>lift_vd()</code> does the same with a function that takes an atomic vector. These factory functions are the inverse operations of <code>lift_dl()</code> and <code>lift_dv()</code>. </p> <p><code>lift_vd()</code> internally coerces the inputs of <code>..f</code> to an atomic vector. The details of this coercion can be controlled with <code>.type</code>. </p> <h3>See Also</h3> <p><code><a href="invoke.html">invoke()</a></code> </p> <h3>Examples</h3> <pre> ### Lifting from ... to list(...) or c(...) x <- list(x = c(1:100, NA, 1000), na.rm = TRUE, trim = 0.9) lift_dl(mean)(x) # Or in a pipe: mean %>% lift_dl() %>% invoke(x) # You can also use the lift() alias for this common operation: lift(mean)(x) # Default arguments can also be specified directly in lift_dl() list(c(1:100, NA, 1000)) %>% lift_dl(mean, na.rm = TRUE)() # lift_dl() and lift_ld() are inverse of each other. # Here we transform sum() so that it takes a list fun <- sum %>% lift_dl() fun(list(3, NA, 4, na.rm = TRUE)) # Now we transform it back to a variadic function fun2 <- fun %>% lift_ld() fun2(3, NA, 4, na.rm = TRUE) # It can sometimes be useful to make sure the lifted function's # signature has no named parameters, as would be the case for a # function taking only dots. The lifted function will take a list # or vector but will not match its arguments to the names of the # input. For instance, if you give a data frame as input to your # lifted function, the names of the columns are probably not # related to the function signature and should be discarded. lifted_identical <- lift_dl(identical, .unnamed = TRUE) mtcars[c(1, 1)] %>% lifted_identical() mtcars[c(1, 2)] %>% lifted_identical() # ### Lifting from c(...) to list(...) or ... # In other situations we need the vector-valued function to take a # variable number of arguments as with pmap(). This is a job for # lift_vd(): pmap(mtcars, lift_vd(mean)) # lift_vd() will collect the arguments and concatenate them to a # vector before passing them to ..f. You can add a check to assert # the type of vector you expect: lift_vd(tolower, .type = character(1))("this", "is", "ok") # ### Lifting from list(...) to c(...) or ... # cross() normally takes a list of elements and returns their # cartesian product. By lifting it you can supply the arguments as # if it was a function taking dots: cross_dots <- lift_ld(cross) out1 <- cross(list(a = 1:2, b = c("a", "b", "c"))) out2 <- cross_dots(a = 1:2, b = c("a", "b", "c")) identical(out1, out2) # This kind of lifting is sometimes needed for function # composition. An example would be to use pmap() with a function # that takes a list. In the following, we use some() on each row of # a data frame to check they each contain at least one element # satisfying a condition: mtcars %>% pmap(lift_ld(some, partial(`<`, 200))) # Default arguments for ..f can be specified in the call to # lift_ld() lift_ld(cross, .filter = `==`)(1:3, 1:3) %>% str() # Here is another function taking a list and that we can update to # take a vector: glue <- function(l) { if (!is.list(l)) stop("not a list") l %>% invoke(paste, .) } ## Not run: letters %>% glue() # fails because glue() expects a list ## End(Not run) letters %>% lift_lv(glue)() # succeeds </pre> <hr /><div style="text-align: center;">[Package <em>purrr</em> version 0.3.4 <a href="00Index.html">Index</a>]</div> </body></html>