relist
Allow ReListing an unlist()ed Object
relist()
is an S3 generic function with a few methods in order
to allow easy inversion of unlist(obj)
when that is used
with an object obj
of (S3) class "relistable"
.
Usage
relist(flesh, skeleton)
"relist"(flesh, skeleton = attr(flesh, "skeleton"))
"relist"(flesh, skeleton = attr(flesh, "skeleton"))
"relist"(flesh, skeleton = attr(flesh, "skeleton"))
"relist"(flesh, skeleton = attr(flesh, "skeleton"))
as.relistable(x)
is.relistable(x)
"unlist"(x, recursive = TRUE, use.names = TRUE)
Arguments
 flesh
 a vector to be relisted
 skeleton
 a list, the structure of which determines the structure of the result
 x
 an R object, typically a list (or vector).
 recursive
 logical. Should unlisting be applied to list
components of
x
?  use.names
 logical. Should names be preserved?
Details
Some functions need many parameters, which are most easily represented in
complex structures, e.g., nested lists. Unfortunately, many
mathematical functions in R, including optim
and
nlm
can only operate on functions whose domain is
a vector. R has unlist()
to convert nested list
objects into a vector representation. relist()
, its methods and
the functionality mentioned here provide the inverse operation to convert
vectors back to the convenient structural representation.
This allows structured functions (such as optim()
) to have simple
mathematical interfaces.
For example, a likelihood function for a multivariate normal model needs a variancecovariance matrix and a mean vector. It would be most convenient to represent it as a list containing a vector and a matrix. A typical parameter might look like
list(mean = c(0, 1), vcov = cbind(c(1, 1), c(1, 0))).However,
optim
cannot operate on functions that take
lists as input; it only likes numeric vectors. The solution is
conversion. Given a function mvdnorm(x, mean, vcov, log = FALSE)
which computes the required probability density, then
ipar < list(mean = c(0, 1), vcov = c bind(c(1, 1), c(1, 0))) initial.param < as.relistable(ipar)
ll < function(param.vector) { param < relist(param.vector, skeleton = ipar)) sum(mvdnorm(x, mean = param$mean, vcov = param$vcov, log = TRUE)) }
optim(unlist(initial.param), ll)
relist
takes two parameters: skeleton and flesh. Skeleton is a sample
object that has the right shape
but the wrong content. flesh
is a vector with the right content but the wrong shape. Invoking
relist(flesh, skeleton)will put the content of flesh on the skeleton. You don't need to specify skeleton explicitly if the skeleton is stored as an attribute inside flesh. In particular, if flesh was created from some object obj with
unlist(as.relistable(obj))
then the skeleton attribute is automatically set. (Note that this
does not apply to the example here, as optim
is creating
a new vector to pass to ll
and not its par
argument.) As long as skeleton
has the right shape, it should be a precise inverse
of unlist
. These equalities hold:
relist(unlist(x), x) == x unlist(relist(y, skeleton)) == y
x < as.relistable(x) relist(unlist(x)) == x
Value

an object of (S3) class
"relistable"
(and "list"
).
See Also
Examples
library(utils)
ipar < list(mean = c(0, 1), vcov = cbind(c(1, 1), c(1, 0)))
initial.param < as.relistable(ipar)
ul < unlist(initial.param)
relist(ul)
stopifnot(identical(relist(ul), initial.param))