# [Rd] relist, an inverse operator to unlist

Gabor Grothendieck ggrothendieck at gmail.com
Mon May 14 01:02:37 CEST 2007

```I suggest you define a "relist" class and then define an unlist
method for it which stores the skeleton as an attribute.  Then
one would not have to specify skeleton in the relist command
so

relist(unlist(relist(x))) === x

1. relist(x) is the same as x except it gets an additional class "relist".
2. unlist(relist(x)) invokes the relist method of unlist on relist(x)
returning another relist object
3. relist(unlist(relist(x))) then recreates relist(x)

On 5/13/07, Andrew Clausen <clausen at econ.upenn.edu> wrote:
> Hi all,
>
> I wrote a function called relist, which is an inverse to the existing
> unlist function:
>
>        http://www.econ.upenn.edu/~clausen/computing/relist.R
>
> Some functions need many parameters, which are most easily represented in
> complex structures.  Unfortunately, many mathematical functions in R,
> including optim, nlm, and grad can only operate on functions whose domain is
> a vector.  R has a function to convert complex objects into a vector
> representation.  This file provides an inverse operation called "unlist" to
> convert vectors back to the convenient structural representation.  Together,
> these functions allow structured functions 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 can't operate on functions that take lists as input; it
> only likes vectors.  The solution is conversion:
>
>         initial.param <- list(mean=c(0, 1), vcov=cbind(c(1, 1), c(1, 0)))
>
>         ll <- function(param.vector)
>         {
>                param <- relist(initial.param, param.vector)
>                -sum(dnorm(x, mean=param\$mean, vcov=param\$vcov, log=TRUE))
>                # note: dnorm doesn't do vcov... but I hope you get the point
>         }
>
>         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(skeleton, flesh)
>
> will put the content of flesh on the skeleton.
>
> As long as "skeleton" has the right shape, it should be a precise inverse
> of unlist.  These equalities hold:
>
>        relist(skeleton, unlist(x)) == x
>        unlist(relist(skeleton, y)) == y
>
> Is there any easy way to do this without my new relist function?  Is there any
> interest in including this in R's base package?  (Or anywhere else?)  Any