On Sun, 9 Mar 2003, Tamas Papp wrote:
> I have a function that returns multiple elements in a list (for the
> sake of the example here, this will simply be a list of two elements,
> a and b, but it is actually five named elements).
>
> This functions computes these values in an iterative manner, and I
> would like to start with an empty list and append the list of return
> values to this list (so that they would remain lists). The Scheme code
> for the resulting list would look something like
>
> (list (list 1 2) (list 3 4) (list 4 5))
>
> I tried to do the same thing in R:
>
> > l <- list()
> > l <- list(unlist(l, recursive=FALSE), list(a=1, b=2)) # OK
> > l <- list(unlist(l, recursive=FALSE), list(a=3, b=4)) # OK
> > l <- list(unlist(l, recursive=FALSE), list(a=5, b=6)) # fails here
>
> I would like to access the elements with eg l[[2]]$a.
>
> Strangely enough (at least to me), I find that the following works:
>
> l <- NULL
> l <- c(l, list(list(a=1, b=2))) # for any values of 1 and 2, of course
;)
>
> Could somebody please explain why the first way doesn't work, and why
> the second does? There seems to be an implicit assumption I am making
> about lists in R which is clearly wrong. Comparisons with Scheme would
> be welcome (does c() "unquote" the lists it is given?)
I think you can usefully regard c() as the vector analogue of (cons).
That is, if you were adding to the head of a list you would expect
(cons (list 3 4) l)
to do what you want, and
c(list(3,4), l)
is the S equivalent. Because S lists are generic vectors rather than
pairlists the natural pasting operating is more symmetric, and
c(l, list(3,4))
adds one element, a list, to the end of l (where (cons) would do something
different).
The unlist() solution doesn't work because recursive=FALSE does one more
level of unlisting than you expect.
> Is there a better way to solve this problem (using another data
> structure)?
Not unless you know in advance how many lists you have.
-thomas