modify {purrr} | R Documentation |
Modify elements selectively
Description
Unlike map()
and its variants which always return a fixed object
type (list for map()
, integer vector for map_int()
, etc), the
modify()
family always returns the same type as the input object.
-
modify()
is a shortcut forx[[i]] <- f(x[[i]]); return(x)
. -
modify_if()
only modifies the elements ofx
that satisfy a predicate and leaves the others unchanged.modify_at()
only modifies elements given by names or positions. -
modify2()
modifies the elements of.x
but also passes the elements of.y
to.f
, just likemap2()
.imodify()
passes the names or the indices to.f
likeimap()
does. -
modify_in()
modifies a single element in apluck()
location.
Usage
modify(.x, .f, ...)
modify_if(.x, .p, .f, ..., .else = NULL)
modify_at(.x, .at, .f, ...)
modify2(.x, .y, .f, ...)
imodify(.x, .f, ...)
Arguments
Details
Since the transformation can alter the structure of the input; it's
your responsibility to ensure that the transformation produces a
valid output. For example, if you're modifying a data frame, .f
must preserve the length of the input.
Value
An object the same class as .x
Genericity
modify()
and variants are generic over classes that implement
length()
, [[
and [[<-
methods. If the default implementation
is not compatible for your class, you can override them with your
own methods.
If you implement your own modify()
method, make sure it satisfies
the following invariants:
modify(x, identity) === x modify(x, compose(f, g)) === modify(x, g) |> modify(f)
These invariants are known as the functor laws in computer science.
See Also
Other map variants:
imap()
,
lmap()
,
map2()
,
map_depth()
,
map_if()
,
map()
,
pmap()
Other modify variants:
map_depth()
,
modify_tree()
Examples
# Convert factors to characters
iris |>
modify_if(is.factor, as.character) |>
str()
# Specify which columns to map with a numeric vector of positions:
mtcars |> modify_at(c(1, 4, 5), as.character) |> str()
# Or with a vector of names:
mtcars |> modify_at(c("cyl", "am"), as.character) |> str()
list(x = sample(c(TRUE, FALSE), 100, replace = TRUE), y = 1:100) |>
list_transpose(simplify = FALSE) |>
modify_if("x", \(l) list(x = l$x, y = l$y * 100)) |>
list_transpose()
# Use modify2() to map over two vectors and preserve the type of
# the first one:
x <- c(foo = 1L, bar = 2L)
y <- c(TRUE, FALSE)
modify2(x, y, \(x, cond) if (cond) x else 0L)
# Use a predicate function to decide whether to map a function:
modify_if(iris, is.factor, as.character)
# Specify an alternative with the `.else` argument:
modify_if(iris, is.factor, as.character, .else = as.integer)