EVOLUTION-MANAGER
Edit File: lmap.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: Apply a function to list-elements of a list</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 lmap {purrr}"><tr><td>lmap {purrr}</td><td style="text-align: right;">R Documentation</td></tr></table> <h2>Apply a function to list-elements of a list</h2> <h3>Description</h3> <p><code>lmap()</code>, <code>lmap_at()</code> and <code>lmap_if()</code> are similar to <code>map()</code>, <code>map_at()</code> and <code>map_if()</code>, with the difference that they operate exclusively on functions that take <em>and</em> return a list (or data frame). Thus, instead of mapping the elements of a list (as in <code>.x[[i]]</code>), they apply a function <code>.f</code> to each subset of size 1 of that list (as in <code>.x[i]</code>). We call those elements <code>list-elements</code>). </p> <h3>Usage</h3> <pre> lmap(.x, .f, ...) lmap_if(.x, .p, .f, ..., .else = NULL) lmap_at(.x, .at, .f, ...) </pre> <h3>Arguments</h3> <table summary="R argblock"> <tr valign="top"><td><code>.x</code></td> <td> <p>A list or data frame.</p> </td></tr> <tr valign="top"><td><code>.f</code></td> <td> <p>A function that takes and returns a list or data frame.</p> </td></tr> <tr valign="top"><td><code>...</code></td> <td> <p>Additional arguments passed on to the mapped function.</p> </td></tr> <tr valign="top"><td><code>.p</code></td> <td> <p>A single predicate function, a formula describing such a predicate function, or a logical vector of the same length as <code>.x</code>. Alternatively, if the elements of <code>.x</code> are themselves lists of objects, a string indicating the name of a logical element in the inner lists. Only those elements where <code>.p</code> evaluates to <code>TRUE</code> will be modified.</p> </td></tr> <tr valign="top"><td><code>.else</code></td> <td> <p>A function applied to elements of <code>.x</code> for which <code>.p</code> returns <code>FALSE</code>.</p> </td></tr> <tr valign="top"><td><code>.at</code></td> <td> <p>A character vector of names, positive numeric vector of positions to include, or a negative numeric vector of positions to exlude. Only those elements corresponding to <code>.at</code> will be modified. If the <code>tidyselect</code> package is installed, you can use <code>vars()</code> and the <code>tidyselect</code> helpers to select elements.</p> </td></tr> </table> <h3>Details</h3> <p>Mapping the list-elements <code>.x[i]</code> has several advantages. It makes it possible to work with functions that exclusively take a list or data frame. It enables <code>.f</code> to access the attributes of the encapsulating list, like the name of the components it receives. It also enables <code>.f</code> to return a larger list than the list-element of size 1 it got as input. Conversely, <code>.f</code> can also return empty lists. In these cases, the output list is reshaped with a different size than the input list <code>.x</code>. </p> <h3>Value</h3> <p>If <code>.x</code> is a list, a list. If <code>.x</code> is a data frame, a data frame. </p> <h3>See Also</h3> <p>Other map variants: <code><a href="imap.html">imap</a>()</code>, <code><a href="invoke.html">invoke</a>()</code>, <code><a href="map2.html">map2</a>()</code>, <code><a href="map_if.html">map_if</a>()</code>, <code><a href="map.html">map</a>()</code>, <code><a href="modify.html">modify</a>()</code> </p> <h3>Examples</h3> <pre> # Let's write a function that returns a larger list or an empty list # depending on some condition. This function also uses the names # metadata available in the attributes of the list-element maybe_rep <- function(x) { n <- rpois(1, 2) out <- rep_len(x, n) if (length(out) > 0) { names(out) <- paste0(names(x), seq_len(n)) } out } # The output size varies each time we map f() x <- list(a = 1:4, b = letters[5:7], c = 8:9, d = letters[10]) x %>% lmap(maybe_rep) # We can apply f() on a selected subset of x x %>% lmap_at(c("a", "d"), maybe_rep) # Or only where a condition is satisfied x %>% lmap_if(is.character, maybe_rep) # A more realistic example would be a function that takes discrete # variables in a dataset and turns them into disjunctive tables, a # form that is amenable to fitting some types of models. # A disjunctive table contains only 0 and 1 but has as many columns # as unique values in the original variable. Ideally, we want to # combine the names of each level with the name of the discrete # variable in order to identify them. Given these requirements, it # makes sense to have a function that takes a data frame of size 1 # and returns a data frame of variable size. disjoin <- function(x, sep = "_") { name <- names(x) x <- as.factor(x[[1]]) out <- lapply(levels(x), function(level) { as.numeric(x == level) }) names(out) <- paste(name, levels(x), sep = sep) out } # Now, we are ready to map disjoin() on each categorical variable of a # data frame: iris %>% lmap_if(is.factor, disjoin) mtcars %>% lmap_at(c("cyl", "vs", "am"), disjoin) </pre> <hr /><div style="text-align: center;">[Package <em>purrr</em> version 0.3.4 <a href="00Index.html">Index</a>]</div> </body></html>