A suite of functions to subset or extract from (potentially complex) lists and list-like structures. Subsetting may occur according to certain data types, using identifier functions, element names or regular expressions to search the list for certain objects.
atomic_elem
and list_elem
are non-recursive functions to extract and replace the atomic and sub-list elements at the top-level of the list tree.
reg_elem
is the recursive equivalent of atomic_elem
and returns the 'regular' part of the list - with atomic elements in the final nodes. irreg_elem
returns all the non-regular elements (i.e. call and terms objects, formulas, etc…). See Examples.
get_elem
returns the part of the list responding to either an identifier function, regular expression or exact element names, or indices applied to all final objects. has_elem
checks for the existence of the searched element and returns TRUE
if a match is found. See Examples.
## Non-recursive (top-level) subsetting and replacing
atomic_elem(l, return = "sublist", keep.class = FALSE)
atomic_elem(l) <- value
list_elem(l, return = "sublist", keep.class = FALSE)
list_elem(l) <- value## Recursive separation of regular (atomic) and irregular (non-atomic) parts
reg_elem(l, recursive = TRUE, keep.tree = FALSE, keep.class = FALSE)
irreg_elem(l, recursive = TRUE, keep.tree = FALSE, keep.class = FALSE)
## Extract elements using a function or regular expression
get_elem(l, elem, recursive = TRUE, DF.as.list = FALSE, keep.tree = FALSE,
keep.class = FALSE, regex = FALSE, …)
## Check for the existence of elements
has_elem(l, elem, recursive = TRUE, DF.as.list = FALSE, regex = FALSE, …)
a list.
a list of the same length as the extracted subset of l
.
a function returning TRUE
or FALSE
when applied to elements of l
, or a character vector of element names or regular expressions (if regex = TRUE
). get_elem
also supports a vector or indices which will be used to subset all final objects.
an integer or string specifying what the selector function should return. The options are:
Int. | String | Description | ||
1 | "sublist" | subset of data frame (default) | ||
2 | "names" | column names | ||
3 | "indices" | column indices | ||
4 | "named_indices" | named column indices | ||
5 | "logical" | logical selection vector | ||
6 | "named_logical" | named logical vector |
Note: replacement functions only replace data, However column names are replaced together with the data.
logical. Should the list search be recursive (i.e. go though all the elements), or just at the top-level?
logical. TRUE
treats data frames like (sub-)lists; FALSE
like atomic elements.
logical. TRUE
always returns the entire list tree leading up to all matched results, while FALSE
drops the top-level part of the tree if possible.
logical. For classed objects: Should the class be retained?
logical. Should regular expression search be used on the list names, or only exact matches?
further arguments to grep
(if regex = TRUE
).
For a lack of better terminology, collapse defines 'regular' R objects as objects that are either atomic or a list. reg_elem
with recursive = TRUE
extracts the subset of the list tree leading up to atomic elements in the final nodes. This part of the list tree is unlistable - calling is_unlistable(reg_elem(l))
will be TRUE
for all lists l
. Conversely, all elements left behind by reg_elem
will be picked up be irreg_elem
(if available). Thus is_unlistable(irreg_elem(l))
is always FALSE
for lists with irregular elements (otherwise irreg_elem
returns an empty list).
If keep.tree = TRUE
, reg_elem
, irreg_elem
and get_elem
always return the entire list tree, but cut off all of the branches not leading to the desired result. If keep.tree = FALSE
, top-level parts of the tree are omitted so far this is possible. For example in a nested list with three levels and one data-matrix in one of the final branches, get_elem(l, is.matrix, keep.tree = TRUE)
will return a list (lres
) of depth 3, from which the matrix can be accessed as lres[[1]][[1]][[1]]
. This however does not make much sense. get_elem(l, is.matrix, keep.tree = FALSE)
will therefore figgure out that it can drop the entire tree and return just the matrix. keep.tree = FALSE
makes additional optimizations if matching elements are at far-apart corners in a nested structure, by only preserving the hierarchy if elements are above each other on the same branch. Thus for a list l <- list(list(2,list("a",1)),list(1,list("b",2)))
calling get_elem(l, is.character)
will just return list("a","b")
.
# NOT RUN {
m <- qM(mtcars)
get_elem(list(list(list(m))), is.matrix)
get_elem(list(list(list(m))), is.matrix, keep.tree = TRUE)
l <- list(list(2,list("a",1)),list(1,list("b",2)))
has_elem(l, is.logical)
has_elem(l, is.numeric)
get_elem(l, is.character)
get_elem(l, is.character, keep.tree = TRUE)
l <- lm(mpg ~ cyl + vs, data = mtcars)
str(reg_elem(l))
str(irreg_elem(l))
get_elem(l, is.matrix)
get_elem(l, "residuals")
get_elem(l, "fit", regex = TRUE)
has_elem(l, "tol")
get_elem(l, "tol")
# }
Run the code above in your browser using DataLab