comprehension: Vectorized Comprehension in R

Description Usage Arguments Details Value Functions Examples

Description

Functions that provide Python-style list (and related) comprehension. Comprehensions convert for loops into lapply functions before evaluation. Support for multiple variables, name assignment, nested loops, custom iterators, if-else statements, and variety of return types included.

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Comp(map = lapply, fun = NULL)

List(loop, clust = NULL, fun = NULL)

Env(loop, clust = NULL)

Vec(loop, clust = NULL, drop.names = FALSE)

Num(loop, clust = NULL, drop.names = FALSE)

Chr(loop, clust = NULL, drop.names = FALSE)

Logical(loop, clust = NULL, drop.names = FALSE)

Mat(loop, clust = NULL, by.col = TRUE)

DF(loop, clust = NULL)

Arguments

map

function, such as lapply, that is used for the comprehension

fun

function to be called on result after comprehension

loop

a for loop with format: for (var in seq) <name => <if (cond)> expr. See "details" below.

clust

cluster to use for parallel computations

drop.names

logical; should names be dropped after conversion? Defaults to FALSE.

by.col

should comprehension on matrix group by columns or rows? Defaults to TRUE.

Details

The comprehension functions parse an R loop expression into lapply functions to allow for more readable code and easy creation and conversion of vectors. The general syntax for a loop expression is as follows:

for (var in seq) <name=> <if (cond)> expr

where <...> denotes optional statements. The seq can be any R object: a list, matrix, data.frame, environment, function, etc. The function iter is called on the seq. So the behavior can be easily described for custom classes or objects. See helpers for functions like zip that can be used with seq.

Multiple variables can be used in var by separating the names with a period ".". For example, i.j is equivalent looping with variables i and j. The downside is that periods cannot be used in the var name. When multiple variables are used, the object received from the sequence at each iteration is split and its elements assigned in order to each of the variables. If the var is i.j and the object received in the iteration was c(2,4,6), then i=2, j=4, and 6 would not be assigned. Since variables are split on periods, i..j could be used to assign the first and third elements, or .i.j the second and third. Any number of variables can be used. Note that the entire object is returned if there are no periods in the name, so use i.. if only the first object is needed.

To provide names within a loop, preface the expression with the desired name for that particular object followed by =. name can be any expression, just make sure to surround any if chain for the name with parentheses, or the R parser will not detect that the assignment operator is associated with the expr. Behind the scenes, the expression on the left-hand side of "=" is wrapped in an sapply function and the results are assigned to the names of the right-hand side result.

The if statement can contain any number of if-else statements and can be nested. Similarly, for statements can be nested any number of times and converted to lapply as long as the expression is a self-contained for loop.

Though comprehensions are functions, both List(for ...) and List[for ...] syntax are supported. See .. for a convenience wrapper around Vec.

The different comprehensions primarily describe the return value, with List return a "list" and Num returning a numeric vector. If the object cannot be converted, then an error will be produced. For Env, the objects must be named. This means that either the name must be assigned within the loop or the loop is performed across a named object and the name is preserved. Another difference is that is some comprehensions - though related to atomic vectors - convert for to sapply while others convert to lapply.

The Comp function is used to create custom comprehensions. It should be supplied with a map function such as lapply that accepts arguments: X for the argument over which the comprehension iterates, FUN a function applied to each element, and ... for additional arguments passed to the FUN. Comp also accepts a post-evaluation function, fun, that is applied to the result. This could be used to ensure that the result complies to some class or other restriction.

Users can also specify a cluster to use. If specified, then a parallel version of lapply or sapply is used based on parLapply and parSapply from the parallel package. This can greatly reduce the calculation time for different operations, but has additional overhead that makes the cost greater than the benefit for relatively small vectors. See auto_cluster for auto-creation.

Value

Determined by the function. List returns an object of class 'list', Num returns a numeric vector, etc. See the descriptions of each function for their return type.

Functions

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
people <- list(
  John = list(age = 30, weight = 180, mood = "happy", gender = "male"),
  April = list(age = 26, weight = 110, mood = "sad", gender = "female"),
  Jill = list(age = 42, weight = 125, mood = "ok", gender = "female")
)

weight_kg <- Num(for (i in people) i$weight/2.2)
gender <- Chr(for (i in people) i$gender)
gender_tab <- List(for (i in c("male", "female")) i = length(which(gender == i)))

Chr(for (..i.j in people) paste0(i, " & ", j))

Chr(for (i.j in items(people)) paste0(i, " is ", j$age, " years old."))

e <- Env(for (i.j in items(people)) i = j$age)
e$John

Num(for (i in 1:10) for (j in 2:6) if (i == j) i^2)

eList documentation built on Jan. 23, 2021, 1:05 a.m.