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
> comments on the implementation?
>
> Cheers,
> Andrew
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>