gen.list
Generate Lists, Vectors and Data Frames with List Comprehension
Functions to transform a base expression containing free variables into a list, a vector, or a data frame based on variable ranges and additional conditions.
Usage
gen.list(expr, ...)gen.vector(expr, ...)
gen.data.frame(expr, ...)
Arguments
- expr
A base expression containing free variables which is evaluated for all combinations of variables, where the combinations of variables are given by the ranges and conditions (see
...
parameters).Expected structure of
expr
:For
gen.list
it may have arbitrary structure (including a list).For
gen.vector
a scalar (i.e., a numeric value of length 1) is expected.For
gen.data.frame
a (named) vector or list is expected which describes one row of the data frame. Default names 'V1', 'V2', ... are used, if no names are given.
Within
expr
it is allowed to use functions and predefined constants from the parent environment.- ...
Arbitrary many variable ranges and conditions. For all free variables occurring in
expr
a range must be assigned, e.g.,x = 1:3, y = 1:5
for an expressionx + y
. At least one variable range is required. The ranges may depend on each other, e.g.,x = 1:3, y = x:3
is allowed. The generated values can be further restricted by conditions (likex <= y
).
Value
The result of gen.list
is a list (a numeric vector for gen.vector
) containing an entry for each combination of the free variables (i.e., the Cartesian product), where all the free variables in expr
are substituted.
The function gen.vector
returns a numeric vector while gen.list
can contain not only numeric values but also more complex substructures (like vectors or lists).
The output of gen.data.frame
is a data frame where each substituted expr
entry is one row.
The base expression expr
should contain a vector or list (a named vector/list if the columns shall be named), such that each entry of this vector becomes a column of the returned data frame.
All expressions and conditions are applied to each combination of the free variables separately, i.e., they are applied row-wise and not vector-wise.
For instance, the term sum(x,y)
(within expr
or a condition) is equivalent to x+y
.
Syntactic Features
There are several syntactic features to be used in variable ranges, conditions, and expressions.
A range for a variable ending with an underscore (like x_
) defines a set of ranges affecting all variables named {varname}_{index}
, e.g. x_1
.
For instance, in gen.vector(x_1 + x_2 + x_3, x_ = 1:5)
the variables x_1, x_2, x_3
are all ranging in 1:5
.
This can be overwritten for each single x_i
, e.g., an additional argument x_3 = 1:3
assigns the range 1:3
to x_3
while x_1
and x_2
keep the range 1:5
.
Expressions and conditions support a ...
-notation which works as follows:
A vector like
c(x_1, ..., x_4)
is a shortcut forc(x_1, x_2, x_3, x_4)
.A named vector like
c(a_1 = x_1, ..., a_3 = x_3)
is a shortcut forc(a_1 = x_1, a_2 = x_2, a_3 = x_3)
.A n-ary function argument like
sum(x_1, ..., x_4)
is a shortcut forsum(x_1, x_2, x_3, x_4)
.Repeated expressions of binary operators can be abbreviated with the
...
expressions as follows:x_1 + ... + x_4
is a shortcut forx_1 + x_2 + x_3 + x_4
. Note that, due to operator precedence,1 + x_1 + ... + x_4
will not work, but1 + (x_1 + ... + x_4)
works as expected.For non-commutative operators,
x_1 - ... - x_4
is a shortcut forx_1 - x_2 - x_3 - x_4
which is evaluated as((x_1 - x_2) - x_3) - x_4
.
The conditions may contain itself list comprehension expressions, e.g., gen.logical.and
to compose and-connected logical expressions.
See Also
gen.list.expr
to generate expressions to be evaluated later,
gen.list.char
to generate lists of characters,
and listcompr for an overview of all list comprehension functions.
Examples
# NOT RUN {
# Compose 10, 11, 20, 21, 22, 30, ..., 33, ..., 90, ..., 99 into a vector
gen.vector(x * 10 + y, x = 1:9, y = 1:x)
# A data frame of all tuples (a_1, a_2, a_3) of whole positive numbers, summing up to 10
gen.data.frame(c(a_1 = x_1, ..., a_3 = x_3), x_ = 1:10, x_1 + ... + x_3 == 10)
# A data.frame containing the numbers in 2:20 and the sum of their divisors
gen.data.frame(c(num = a, sumdiv = sum(gen.vector(x, x = 1:(a-1), a %% x == 0))),
a = 2:20)
# Return perfect numbers between 2 and 100 (number equals the sum of divisors)
gen.vector(a, a = 2:100, a == sum(gen.vector(x, x = 1:(a-1), a %% x == 0)))
# }