relist
and split
are 2 common ways of grouping the elements
of a vector-like object into a list-like object. The IRanges package
defines relist
and split
methods that operate on a
Vector object and return a List object. Because relist
and split
both impose severe restrictions on
the kind of grouping that they support (e.g. every element in the input
object needs to go in a group and can only go in one group), the
IRanges package introduces the extractList
generic function
for performing arbitrary groupings.
relist
, split
, and extractList
have in common that
they return a list-like value where each list element has the same class
as the original vector-like object. Thus they need to be able to select
the appropriate List concrete subclass to use for this returned
value. This selection is performed by relistToClass
and
is based only on the class of the original object.
## relist()
## --------
"relist"(flesh, skeleton)
"relist"(flesh, skeleton)
## splitAsList() and split()
## -------------------------
splitAsList(x, f, drop=FALSE)
"split"(x, f, drop=FALSE)
## extractList()
## -------------
extractList(x, i)
## relistToClass()
## --------------------------
relistToClass(x)
skeleton
matters. Its exact content is ignored.
f
is a factor).
skeleton
, the content here matters
(see Details section below).
Note that i
can be a Ranges object (a particular type of
list-like object), and, in that case, extractList
is particularly
fast (this is a common use case).
relist
method behaves like utils::relist
except that it
returns a List object. If skeleton
has names, then they are
propagated to the returned value.splitAsList
and the split
method behave like
base::split
except that they return a List object.
The difference between splitAsList
and split
is that the
former always returns a List object while the latter can return
an ordinary list (e.g. when x
and f
are ordinary vectors
and/or factors).extractList
returns a list-like object parallel to i
and with
the same "shape" as i
(i.e. same element lengths).
If i
has names, then they are propagated to the returned value.All these functions (except relistToClass
) return a
list-like object where the list elements have the same class as x
.
relistToClass
gives the exact class of the returned object.
extractList(x, i)
is equivalent to:
relist(x[unlist(i)], i)An exception is made when
x
is a data-frame-like object. In that
case x
is subsetted along the rows, that is, extractList(x, i)
is equivalent to:
relist(x[unlist(i), ], i)This is more or less how the default method is implemented, except for some optimizations when
i
is a Ranges object. relist
and split
can be seen as specialized versions of
extractList
:
relist(flesh, skeleton) is equivalent to extractList(flesh, PartitioningByEnd(skeleton))
split(x, f) is equivalent to
extractList(x, split(seq_along(f), f))
It is good practise to use extractList
only for cases not covered
by relist
or split
. Whenever possible, using relist
or split
is preferred as they will always perform more efficiently.
In addition their names carry meaning and are familiar to most R
users/developers so they'll make your code easier to read/understand.
Note that the transformation performed by relist
or split
is always reversible (via unlist
and unsplit
, respectively),
but the transformation performed by extractList
is not.
## On an Rle object:
x <- Rle(101:105, 6:2)
i <- IRanges(6:10, 16:12, names=letters[1:5])
extractList(x, i)
## On a DataFrame object:
df <- DataFrame(X=x, Y=LETTERS[1:20])
extractList(df, i)
Run the code above in your browser using DataLab