Version: | 0.0.3 |
Title: | Elegant Data Manipulation with Lenses |
Description: | Provides tools for creating and using lenses to simplify data manipulation. Lenses are composable getter/setter pairs for working with data in a purely functional way. Inspired by the 'Haskell' library 'lens' (Kmett, 2012) https://hackage.haskell.org/package/lens. For a fairly comprehensive (and highly technical) history of lenses please see the 'lens' wiki https://github.com/ekmett/lens/wiki/History-of-Lenses. |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
LazyData: | true |
ByteCompile: | true |
RoxygenNote: | 6.0.1 |
URL: | http://cfhammill.github.io/lenses, https://github.com/cfhammill/lenses |
BugReports: | https://github.com/cfhammill/lenses/issues |
Suggests: | testthat |
Imports: | magrittr, tidyselect, rlang |
Collate: | 'verbs.R' 'lens.R' 'array-lenses.R' 'base-lenses.R' 'utils.R' 'dataframe-lenses.R' 'utils-pipe.R' |
NeedsCompilation: | no |
Packaged: | 2019-03-03 17:00:51 UTC; chammill |
Author: | Chris Hammill [aut, cre, trl], Ben Darwin [aut, trl] |
Maintainer: | Chris Hammill <cfhammill@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2019-03-06 14:40:03 UTC |
Pipe operator
Description
See magrittr::%>%
for details.
Usage
lhs %>% rhs
Compose lenses
Description
Compose two lenses to produce a new lens which represents
focussing first with the first lens, then with the second.
A view
using the resulting composite lens will first view
using
the first, then the second, while an set
will view
via the first lens,
set
into the resulting piece with the second, and then replace the
updated structure in the first with set
. Lens composition
is analogous to the .
syntax of object-oriented programming or to
a flipped version of function composition.
Usage
l %.% m
Arguments
l |
|
m |
the second lens |
Examples
lst <- list(b = c(3,4,5))
lns <- index_l("b") %.% index_l(2)
lst %>% view(lns) # returns 4
lst %>% set(lns, 1) # returns list(b = c(3,2,5))
lst # returns list(b = c(3,4,5))
Construct a lens into an attribute
Description
The lens version of attr
and attr<-
Usage
attr_l(attrib)
Arguments
attrib |
A length one character vector indicating the attribute to lens into. |
Examples
(x <- structure(1:10, important = "attribute"))
view(x, attr_l("important"))
set(x, attr_l("important"), "feature")
Attributes lens
Description
The lens equivalent of attributes and attributes<-
Usage
attributes_l
Format
An object of class lens
of length 2.
Examples
(x <- structure(1:10, important = "attribute"))
view(x, attributes_l)
set(x, attributes_l, list(important = "feature"))
Body lens
Description
A lens into the body of a function. The lens equivalent of body and body<-. You probably shouldn't use this.
Usage
body_l
Format
An object of class lens
of length 2.
Examples
inc2 <- function(x) x + 2
view(inc2, body_l)
inc4 <- set(inc2, body_l, quote(x + 4))
inc4(10)
Convenient lens composition
Description
A lens version of purrr::pluck. Takes a series element indicators and creates a composite lens.
Usage
c_l(...)
Arguments
... |
index vectors or lenses |
Details
length one vectors are converted to index_l,
length one logical vectors and numeric vectors that are negative are converted to indexes_l,
larger vectors are converted to indexes_l,
lenses are composed as is.
See examples for more
Examples
view(iris, c_l("Petal.Length", 10:20, 3))
sepal_l <- index("Sepal.Length")
view(iris, c_l(sepal_l, id_l, 3))
Class lens
Description
A lens into the class of an object. Lens equivalent of class and class<-.
Usage
class_l
Format
An object of class lens
of length 2.
Examples
x <- 1:10
view(x, class_l)
set(x, class_l, "super_integer")
A lens into the column names of an object
Description
The lens version of colnames
and colnames<-
Usage
colnames_l
Format
An object of class lens
of length 2.
Examples
x <- matrix(1:4, ncol = 2)
colnames(x) <- c("first", "second")
x
view(x, colnames_l)
set(x, colnames_l, c("premiere", "deuxieme"))
Column lens
Description
Create a lens into a set of columns
Usage
cols_l(cols, drop = FALSE)
Arguments
cols |
the columns to focus on |
drop |
whether or not to drop dimensions with length 1 |
Examples
x <- matrix(1:4, ncol = 2)
colnames(x) <- c("first", "second")
x
view(x, cols_l(1))
view(x, cols_l("second"))
set(x, cols_l(1), c(20,40))
Conditional lens
Description
view is equivalent to Filter(f,d)
,
set replaces elements that satisfy f
with elements
of x.
Usage
cond_il(f)
Arguments
f |
the predicate (logical) function |
Details
This lens is illegal because set-view
is not satisfied,
multiple runs of the same lens will reference potentially
different elements.
Lens into the diagonal of a matrix
Description
A lens into a matrix's diagonal elements
Usage
diag_l
Format
An object of class lens
of length 2.
Dims lens
Description
A lens into an objects dimensions
Usage
dim_l
Format
An object of class lens
of length 2.
Examples
x <- 1:10
(y <- set(x, dim_l, c(2,5)))
view(y, dim_l)
Dimnames lens
Description
A lens into the dimnames of an object. Lens equivalent of dimnames and dimnames<-.
Usage
dimnames_l
Format
An object of class lens
of length 2.
Examples
x <- matrix(1:4, ncol = 2)
colnames(x) <- c("first", "second")
x
view(x, dimnames_l)
set(x, dimnames_l, list(NULL, c("premiere", "deuxieme")))
Conditional trim lens
Description
A lens into all elements starting from the first element that doesn't satisfy a predicate. Essentially the complement of take_while_il
Usage
drop_while_il(f)
Arguments
f |
the predicate (logical) function |
Environment lens
Description
A lens into the environment of an object. This is the lens version of environment and environment<-
Usage
env_l
Format
An object of class lens
of length 2.
Examples
x <- 10
f <- (function(){x <- 2; function() x + 1})()
f
f()
view(f, env_l)$x
g <- over(f, env_l, parent.env)
g()
Filter lens
Description
Create an illegal lens into the result of a filter. Arguments are interpreted with non-standard evaluation as in dplyr::filter
Usage
filter_il(...)
Arguments
... |
unquoted NSE filter arguments |
Examples
head(view(iris, filter_il(Species == "setosa")))
head(over(iris,
filter_il(Species == "setosa") %.% select_l(-Species),
function(x) x + 10))
Filter lens
Description
Create a lawful lens into the result of a filter. This focuses only columns not involved in the filter condition.
Usage
filter_l(...)
Arguments
... |
unquoted NSE filter arguments |
Examples
head(view(iris, filter_l(Species == "setosa"))) # Note Species is not seen
head(over(iris, filter_l(Species == "setosa"), function(x) x + 10))
A lens into the first element
Description
Lens version of x[[1]]
and x[[1]] <- val
x <- 1:10
view(x, first_l)
set(x, first_l, 50)
[[1]: R:[1 [[1]: R:[1
Usage
first_l
Format
An object of class lens
of length 2.
Formals lens
Description
A lens equivalent of formals and formals<-, allowing you to change the formal arguments of a function. As with body_l you probably shouldn't use this.
Usage
formals_l
Format
An object of class lens
of length 2.
Examples
f <- function(x) x + y + 7
view(f, formals_l)
g <- set(f, formals_l, list(x = 1, y = 2))
g()
The identity (trivial lens)
Description
This lens focuses on the whole object
Usage
id_l
Format
An object of class lens
of length 2.
Examples
x <- 1:10
view(x, id_l)
head(set(x, id_l, iris))
Construct a lens into an index/name
Description
This is the lens version of [[
Usage
index_l(el)
index(el)
Arguments
el |
The element the lens should point to
can be an |
Functions
-
index
: shorthand
Examples
x <- 1:10
view(x, index_l(1))
set(x, index(5), 50)
head(view(iris, index(2)))
Construct a lens into a subset of an object
Description
This is the lens version of [
Usage
indexes_l(els)
indexes(els)
Arguments
els |
a subset vector, can be |
Functions
-
indexes
: shorthand
Examples
x <- 1:10
view(x, indexes_l(3:5))
set(x, indexes_l(c(1,10)), NA)
head(view(iris, indexes_l(c("Sepal.Length", "Species"))))
A lens into the last element
Description
Lens version of x[[length(x)]]
and x[[length(x)]] <- val
[[length(x)]: R:[length(x) [[length(x)]: R:[length(x)
Usage
last_l
Format
An object of class lens
of length 2.
Examples
x <- 1:10
view(x, last_l)
set(x, last_l, 50)
Construct a lens
Description
A lens
represents the process of focusing on a specific part of a data structure.
We represent this via a view
function and
an set
function, roughly corresponding to object-oriented
"getters" and "setters" respectively.
Lenses can be composed to access or modify deeply nested
structures.
Usage
lens(view, set, getter = FALSE)
Arguments
view |
A function that takes a data structure of a certain type and returns a subpart of that structure |
set |
A function that takes a data structure of a certain type
and a value and returns a new data structure with the given subpart
replaced with the given value. Note that |
getter |
Default is |
Details
Lenses are popular in functional programming because they allow you to build pure, compositional, and re-usable "getters" and "setters".
As noted in the README, using lens
directly incurs the following obligations
(the "Lens laws"):
Get-Put: If you get (view) some data with a lens, and then modify (set) the data with that value, you get the input data back.
Put-Get: If you put (set) a value into some data with a lens, then get that value with the lens, you get back what you put in.
Put-Put: If you put a value into some data with a lens, and then put another value with the same lens, it's the same as only doing the second put.
"Lenses" which do not satisfy these properties should be documented accordingly. By convention, such objects present in this library are suffixed by "_il" ("illegal lens").
Examples
third_l <- lens(view = function(d) d[[3]],
set = function(d, x){ d[[3]] <- x; d })
view(1:10, third_l) # returns 3
set(1:10, third_l, 10) # returns c(1:2, 10, 4:10)
Levels lens
Description
A lens into the levels of an object. Usually this is factor levels. Lens equivalent of levels and levels<-.
Usage
levels_l
Format
An object of class lens
of length 2.
Examples
x <- factor(c("a", "b"))
view(x, levels_l)
set(x, levels_l, c("A", "B"))
Lens into lower diagonal elements
Description
Create a lens into the lower diagonal elements of a matrix
Usage
lower_tri_l(diag = FALSE)
Arguments
diag |
whether or not to include the diagonal |
Examples
(x <- matrix(1:9, ncol = 3))
view(x, lower_tri_l())
view(x, lower_tri_l(diag = TRUE))
set(x, lower_tri_l(), c(100, 200, 300))
Promote a lens to apply to each element of a list
Description
Create a new lens that views and sets each element of the list.
Usage
map_l(l)
Arguments
l |
the lens to promote |
Details
Uses lapply under the hood for view and mapply under the hood for set. This means that set can be given a list of values to set, one for each element. If the input or update are lists this lens always returns a list. If the input and update are vectors this lens will return a vector.
Examples
(ex <- replicate(10, sample(1:5), simplify = FALSE))
view(ex, map_l(index(1)))
set(ex, map_l(index(1)), 11:20)
A lens into the names of an object
Description
The lens versions of names
and names<-
.
Usage
names_l
Format
An object of class lens
of length 2.
Examples
view(iris, names_l)
head(set(iris, names_l, LETTERS[1:5]))
Bind data to a lens
Description
To flatten lens composition, you can prespecify the data the lens with be applied to by constructing an objectoscope. These can be integrated easily with normal data pipelines.
Usage
oscope(d, l = id_l)
Arguments
d |
The data for interest |
l |
The lens to bind the data to. Defaults to the identity lens |
Examples
list(a = 5, b = 1:3, c = 8) %>%
oscope() %.%
index_l("b") %.%
index_l(1) %>%
set(10)
Map a function over a lens
Description
Get the data pointed to by a lens, apply a function and replace it with the result.
Usage
over(d, l, f)
Arguments
d |
the data (or an oscope) |
l |
the lens (or the function if |
f |
the function (or nothing if |
Examples
third_l <- index(3)
over(1:5, third_l, function(x) x + 2)
# returns c(1:2, 5, 4:5)
Map a function over a list lens
Description
Apply the specified function to each element of the subobject.
Usage
over_map(d, l, f)
Arguments
d |
the data |
l |
the lens |
f |
the function to use, potentially a |
Map a function over an in scope lens
Description
Apply the specified function with named elements of the viewed data in scope. Similar to dplyr::mutate
Usage
over_with(d, l, f)
Arguments
d |
the data |
l |
the lens |
f |
the function to use, potentially a |
Examples
iris %>% over_with(id_l, ~ Sepal.Length)
Lens into a new dimension(s)
Description
Construct a lens that is a view of the data with a new set of dimensions. Both view and set check that the new dimensions match the number of elements of the data.
Usage
reshape_l(dims)
Arguments
dims |
a vector with the new dimensions |
Examples
x <- 1:9
view(x, reshape_l(c(3,3)))
set(x, reshape_l(c(3,3)) %.% diag_l, 100)
Reverse lens
Description
Lens into the reverse of an object.
Usage
rev_l
Format
An object of class lens
of length 2.
Examples
x <- 1:10
view(x, rev_l)
set(x, rev_l, 11:20)
A lens into the row names of an object
Description
The lens version of rownames
and rownames<-
Usage
rownames_l
Format
An object of class lens
of length 2.
Examples
x <- matrix(1:4, ncol = 2)
rownames(x) <- c("first", "second")
x
view(x, rownames_l)
set(x, rownames_l, c("premiere", "deuxieme"))
Row lens
Description
Create a lens into a set of rows
Usage
rows_l(rows, drop = FALSE)
Arguments
rows |
the rows to focus on |
drop |
whether or not to drop dimensions with length 1 |
Examples
x <- matrix(1:4, ncol = 2)
rownames(x) <- c("first", "second")
x
view(x, rows_l(1))
view(x, rows_l("second"))
set(x, rows_l(1), c(20,40))
Tidyselect elements by name
Description
Create a lens into a named collection. On set names of the input are not changed. This generalizes dplyr::select to arbitrary named collections and allows updating.
Usage
select_l(...)
Arguments
... |
An expression to be interpreted by tidyselect::vars_select which is the same interpreter as dplyr::select |
Examples
lets <- setNames(seq_along(LETTERS), LETTERS)
set(lets, select_l(G:F, A, B), 1:4) # A and B are 3,4 for a quick check
Set one lens to the view of another
Description
Set one lens to the view of another
Usage
send(d, l, m)
Arguments
d |
the data |
l |
the lens to view through |
m |
the lens to set into |
Set one lens to the view of another (transformed)
Description
Set one lens to the view of another (transformed)
Usage
send_over(d, l, m, f)
Arguments
d |
the data |
l |
the lens to view through |
m |
the lens to set into |
f |
the function to apply to the viewed data |
Modify data with a lens
Description
Set the subcomponent of the data referred to by a lens
with a new value. See lens for details. Merely dispatches
to the set
component of the lens.
Usage
set(d, l, x)
Arguments
d |
the data, or an oscope |
l |
the lens, or in the case of an |
x |
the replacement value, or nothing in the case of an |
Slab lens
Description
Create a lens into a chunk of an array (hyperslab). Uses
the same syntactic rules as [
.
Usage
slab_l(..., drop = FALSE)
Arguments
... |
arguments as they would be passed to |
drop |
whether or not to drop dimensions with length 1. Only
applies to |
Examples
(x <- matrix(1:4, ncol = 2))
view(x, slab_l(2,)) # x[2,, drop = FALSE]
view(x, slab_l(2, 2)) # x[2,2, drop = FALSE]
set(x, slab_l(1,1:2), c(10,20))
Slice lens
Description
Create a lens into a specific slice of a specific dimension of a multidimensional object. Not to be confused with dplyr slice.
Usage
slice_l(dimension, slice, drop = FALSE)
Arguments
dimension |
the dimension to slice |
slice |
the slice index |
drop |
whether or not to drop dimensions with length 1. Only applies to view. |
Examples
(x <- matrix(1:4, ncol = 2))
view(x, slice_l(1, 2)) # x[2,, drop = FALSE]
view(x, slice_l(2, 2)) # x[,2, drop = FALSE]
set(x, slice_l(1,1), c(10,20))
Slot lens
Description
The lens equivalent of @
and @<-
for getting and setting S4 object slots.
Usage
slot_l(slot)
Arguments
slot |
the name of the slot |
Examples
new_class <- setClass("new_class", slots = c(x = "numeric"))
(x <- new_class())
view(x, slot_l("x"))
set(x, slot_l("x"), 1:10)
Matrix transpose lens
Description
Lens into the transpose of a matrix
Usage
t_l
Format
An object of class lens
of length 2.
Examples
(x <- matrix(1:4, ncol = 2))
view(x, t_l)
set(x, t_l, matrix(11:14, ncol = 2))
Construct a lens into a prefix of a vector
Description
This constructs a lens into the first n
elements
of an object or the if negative indexing is used,
as many as length(x) - n
.
Usage
take_l(n)
Arguments
n |
number of elements to take, or if negative the number of elements at the end to not take. |
Examples
x <- 1:10
view(x, take_l(3))
view(x, take_l(-7))
set(x, take_l(2), c(100,200))
set(x, take_l(-8), c(100,200))
Conditional head lens
Description
A lens into the elements from the beginning of a structure until the last element that satisfies a predicate.
Usage
take_while_il(f)
Arguments
f |
the predicate (logical) function |
Details
This lens is illegal because set-view
is not satisfied,
multiple runs of the same lens will reference potentially
different elements.
Promote a function to a getter
lens
Description
Create a getter
lens from a function.
Usage
to_l(f)
Arguments
f |
The function to promote. |
Examples
# This wouldn't make sense as a general legal lens, but fine as a `getter`
sqrt_l <- to_l(sqrt)
iris_root <- index(1) %.% index(1) %.% sqrt_l
sqrt(iris[[1]][[1]])
iris %>% view(iris_root)
tryCatch(iris %>% set(iris_root, 2)
, error = function(e) "See, can't do that")
Lens into a list of rows
Description
A lens that creates a list-of-rows view of a data.frame
Usage
transpose_l
Format
An object of class lens
of length 2.
Unlist lens
Description
A lens between a list and an unrecursively unlisted object.
Usage
unlist_l
Format
An object of class lens
of length 2.
Examples
(x <- list(x = list(y = 1:10)))
view(x, unlist_l)
set(x, unlist_l %.% unlist_l, rep("hello", 10))
Lens into upper diagonal elements
Description
Create a lens into the upper diagonal elements of a matrix
Usage
upper_tri_l(diag = FALSE)
Arguments
diag |
whether or not to include the diagonal (x <- matrix(1:9, ncol = 3)) view(x, upper_tri_l()) view(x, upper_tri_l(diag = TRUE)) set(x, upper_tri_l(), c(100, 200, 300)) |
View data with a lens
Description
Get the subcomponent of the data referred to by a lens. This function
merely dispatches to the view
component of the lens.
Usage
view(d, l)
Arguments
d |
the data |
l |
the lens |