relist                 package:utils                 R Documentation

Allow Re-Listing an unlist()ed Object

Description:

     '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)
     ## Default S3 method:
     relist(flesh, skeleton = attr(flesh, "skeleton"))
     ## S3 method for class 'factor':
     relist(flesh, skeleton = attr(flesh, "skeleton"))
     ## S3 method for class 'list':
     relist(flesh, skeleton = attr(flesh, "skeleton"))
     ## S3 method for class 'matrix':
     relist(flesh, skeleton = attr(flesh, "skeleton"))

     as.relistable(x)
     is.relistable(x)

     ## S3 method for class 'relistable':
     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()', it's 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=cbind(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"').

Author(s):

     R Core, based on a code proposal by Andrew Clausen.

See Also:

     'unlist'

Examples:

      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))

