The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Title: Minimal Implementation of Functional Lenses
Version: 0.1.0
Description: Provides utilities to create and use lenses to simplify data manipulation. Lenses are composable getter/setter pairs that provide a functional approach to manipulating deeply nested data structures, e.g., elements within list columns in data frames. The implementation is based on the earlier 'lenses' R package https://github.com/cfhammill/lenses, which was inspired by the Haskell 'lens' package by Kmett (2012) https://github.com/ekmett/lens, one of the most widely referenced implementations of lenses. For additional background and history on the theory of lenses, see the 'lens' package wiki: https://github.com/ekmett/lens/wiki/History-of-Lenses.
License: MIT + file LICENSE
Encoding: UTF-8
RoxygenNote: 7.3.2
Imports: rlang, S7, vctrs
Collate: 'lens.R' 'verbs.R' 'base-lenses.R' 'dataframe-lenses.R' 'tinylens-package.R' 'zzz.R'
Suggests: tidyselect, tinytest
URL: https://github.com/arbelt/tinylens
BugReports: https://github.com/arbelt/tinylens/issues
NeedsCompilation: no
Packaged: 2024-12-06 15:27:24 UTC; albert
Author: Albert Wang [aut, cre, cph]
Maintainer: Albert Wang <albert_z_wang@harvard.edu>
Repository: CRAN
Date/Publication: 2024-12-09 13:30:02 UTC

tinylens: Minimal Implementation of Functional Lenses

Description

Provides utilities to create and use lenses to simplify data manipulation. Lenses are composable getter/setter pairs that provide a functional approach to manipulating deeply nested data structures, e.g., elements within list columns in data frames. The implementation is based on the earlier 'lenses' R package https://github.com/cfhammill/lenses, which was inspired by the Haskell 'lens' package by Kmett (2012) https://github.com/ekmett/lens, one of the most widely referenced implementations of lenses. For additional background and history on the theory of lenses, see the 'lens' package wiki: https://github.com/ekmett/lens/wiki/History-of-Lenses.

Author(s)

Maintainer: Albert Wang albert_z_wang@harvard.edu [copyright holder]

See Also

Useful links:


Compose two lenses

Description

The resulting lens first applies the left lens, then the right lens.

Usage

l %.% m

Arguments

l

First lens

m

Second lens

Value

A new lens

Examples

d <- list(list(a = 1, b = 2), list(a = 4, b = 9))
l <- index_l(1)
m <- index_l("b")
view(d, l %.% m)

Attributes lens

Description

Lens into a named attribute of an object.

Usage

attr_l(name)

Arguments

name

Name of the attribute to lens into

Value

A lens that selects the specified attribute

Examples

x <- 1:10
attr(x, "label") <- "my_label"
l <- attr_l("label")
view(x, l)
set(x, l, "new_label")

Lens for accessing and modifying nested elements of a list or vector

Description

Convenience function that mirrors purrr::pluck().

Usage

c_l(...)

Arguments

...

A sequence of lenses and/or integers/logical vectors

Value

A lens that combines all specified lenses (left to right).

Examples

d <- list(a = list(b = 1, c = 2), b = list(b = 3, c = 4))
l <- c_l("a", "b")
view(d, l)

Filter ilens

Description

This function returns an illegal lens that filters according to the specified conditions.

Usage

filter_il(...)

Arguments

...

Conditions to filter by

Details

Conditions are evaluated in the context of the data frame.

Value

A lens that filters the specified rows

Examples

d <- data.frame(x = 1:10, y = 11:20, z = 21:30)
l <- filter_il(x > 5)
# get the rows where x is greater than 5
view(d, l)
# set the rows where x is greater than 5 to 8
set(d, l, 8)
# set y value to 8 where x is greater than 5
set(d, l %.% select_l(y), 8)

Identity lens

Description

Trivial identity lens: returns and sets the object itself.

Usage

id_l

Format

An object of class tinylens::lens (inherits from S7_object) of length 1.

Examples

x <- 1:10
view(x, id_l)

Index lens

Description

Lens into a single element of a list.

Usage

index_l(i)

Arguments

i

Index of the element to lens into

Details

This lens performs indexing using double bracket notation, i.e., x[[i]].

Value

A lens that selects the specified element

Examples

x <- list(a = 1, b = 2)
l <- index_l("a")
view(x, l)

Subset lens

Description

This function returns a lens that subsets the object in a generalized way.

Usage

indices_l(...)

i_l(...)

Arguments

...

Conditions to subset by. Unnamed arguments are used as indices. Named arguments are passed along to [ for viewing and are removed for setting.

Value

A lens that subsets the object by the specified indices

Examples

d <- data.frame(x = 1:10, y = 11:20, z = 21:30)
l <- indices_l(1, 1)
# get the first row of first column
view(d, l)
# set the first row of first column
set(d, l, 1)

# get the first row
l <- indices_l(1,)
view(d, l)
# set the first row
set(d, l, 1)

Create a lens

Description

A lens is a pair of functions that can be used to view and set a value in an object. Lenses are implemented as S7 classes.

Usage

lens(view, set = NULL)

Arguments

view

A function that takes an object and returns a value

set

A function that takes an object and a value and returns a new object

Details

A "proper" lens should satisfy the following so-called "lens laws":

These laws are not enforced by tinylens, but you should strive to follow them when creating your own lenses.

A best effort has been made to ensure that these laws hold for the lenses provided by tinylens, but this is trickier than it might seem because of how R handles subset assignments.

Value

A lens with the specified view and set functions

Examples

# create a trivial identity lens
l <- lens(view = function(x) x, set = function(x, value) value)

Lens into a list or vector

Description

This lens allows you to access and modify elements of a list or vector based on their position or a logical condition.

Usage

map_l(l, .ptype = NULL)

Arguments

l

A lens that selects the elements to lens into

.ptype

The prototype of the data structure to return

Value

A lens that selects the specified elements

Examples

d <- list(list(a = 1, b = 2), list(a = 4, b = 9))
l <- index_l("a")
view(d, map_l(l))
over_map(d, map_l(l), sqrt)

Names lens

Description

Lens into the names attribute of an object. This uses rlang::names2 to better handle NULL names.

Usage

names_l

Format

An object of class tinylens::lens (inherits from S7_object) of length 1.

Examples

x <- letters[1:10]
names(x) <- letters[1:10]
view(x, names_l)
over(x, names_l, toupper)

Modify the focused part of a data structure

Description

Modify the focused part of a data structure

Usage

over(d, l, f)

Arguments

d

The data structure to view

l

The lens to apply

f

The function to apply

Value

The modified data structure


Map a function over a list lens

Description

Apply a function to each element of a list returned by a lens. Using over in such cases would require a "lifted" function, which is often unergonomic.

Usage

over_map(d, l, f)

Arguments

d

The data structure to modify

l

The list-returning lens to apply

f

The function to apply to each element of the list

Value

The modified data structure

Examples

d <- list(list(a = 1, b = 2), list(a = 4, b = 9))
l <- map_l(index_l("a"))
over_map(d, l, sqrt)

Rows lens

Description

This function returns a lens that selects the specified rows.

Usage

rows_l(idx)

Arguments

idx

The rows to select

Value

A lens that selects the specified rows

Examples

d <- data.frame(x = 1:10, y = 11:20, z = 21:30)
l <- rows_l(1:2)
# get the first two rows
view(d, l)
# set the first two rows
set(d, l, 1:2)

include verbs.R include lens.R Select lens

Description

This function returns a lens that selects the specified columns. Requires tidyselect to be installed.

Usage

select_l(...)

Arguments

...

Columns to select

Value

A lens that selects the specified columns

Examples

d <- data.frame(x = 1:10, y = 11:20, z = 21:30)
l <- select_l(x, y)
# get the x and y columns
view(d, l)
# set the x and y columns
set(d, l, 1)

Set the focused part of a data structure

Description

Set the focused part of a data structure

Usage

set(d, l, x)

Arguments

d

The data structure to view

l

The lens to apply

x

The value to set

Value

The modified data structure


Slice lens

Description

Lens into a slice of a vector.

Usage

slice_l(idx)

Arguments

idx

Indices of the elements to lens into

Details

This lens performs indexing using single bracket notation, i.e., x[idx].

Value

A lens that selects the specified slice

Examples

x <- letters[1:10]
l <- slice_l(1:5)
view(x, l)

Vector data lens

Description

Allows mutation of vector data while preserving attributes, e.g., labels or names.

Usage

vec_data_l

Format

An object of class tinylens::lens (inherits from S7_object) of length 1.

Examples

x <- letters[1:10]
names(x) <- letters[1:10]
# toy function that strips names; most functions from `stringr` do this
f <- function(x) toupper(unname(x))
# apply the function without losing attributes
over(x, vec_data_l, f)

View the focused part of a data structure

Description

view() applies a lens to a data structure and returns the focused part.

set() applies a lens to a data structure and sets the focused part.

over() applies a lens to a data structure and modifies the focused part using a function.

Usage

view(d, l)

Arguments

d

The data structure to view

l

The lens to apply

Value

The part of the data structure focused by the lens

Examples

x <- 1:10
names(x) <- letters[1:10]
view(x, names_l)
set(x, names_l, LETTERS[1:10])
over(x, names_l, toupper)

Predicate ilens

Description

Illegal lens into elements of a vector that satisfy a predicate.

Usage

where_il(p)

Arguments

p

A predicate function

Value

A lens that selects the elements that satisfy the predicate

Examples

d <- 1:10
l <- where_il(\(x) x %% 2 == 0)
view(d, l)
over(d, l, \(x) x / 2)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.