`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"`

.

```
relist(flesh, skeleton)
# S3 method for default
relist(flesh, skeleton = attr(flesh, "skeleton"))
# S3 method for factor
relist(flesh, skeleton = attr(flesh, "skeleton"))
# S3 method for list
relist(flesh, skeleton = attr(flesh, "skeleton"))
# S3 method for matrix
relist(flesh, skeleton = attr(flesh, "skeleton"))
```as.relistable(x)
is.relistable(x)

# S3 method for relistable
unlist(x, recursive = TRUE, use.names = TRUE)

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?

an object of (S3) class `"relistable"`

(and `"list"`

).

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 variance-covariance 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)) == yx <- as.relistable(x) relist(unlist(x)) == x

```
# NOT RUN {
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))
# }
```

Run the code above in your browser using DataLab