[R] list of data.frames?

Wacek Kusnierczyk Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Wed Jun 17 22:06:56 CEST 2009


Steve Jaffe wrote:
> I'm trying to build up a list of data.frames by "appending" one by one. 
>
> If x,y,z are data.frames, I can do
>
> somelist <- list(x, y, z)  (or even somelist <- list(x=x, y=y, z=z) to get
> names)
>
> But if I start with 
>
> somelist <- list(x,y) and now want to go from this to list(x,y,z) I'm stuck.
> I've tried
>
>   
> append(somelist, z)
> c(somelist, z)
>   

return a list whose elements are the elements of somelist and the
*elements* of z, not z itself -- z, a data frame, is a *list*, and it's
elements are the vectors that are its columns.

> list(somelist, z)
>   

makes a two-element list, with somelist and z as the elements.

you may want to consult the 'help' pages, though they do not appear to
be particularly carefully crafted.  ?append explains:

"
Vector Merging

Description:
     Add elements to a vector.

Usage:
     append(x, values, after = length(x))

Arguments:
       x: the vector to be modified.
  values: to be included in the modified vector.
"

which is suggestive (perhaps except for the name 'values') of that
*values*, rather than its elements, is included in the modified vector,
while the opposite is true:

    append(list(1), 2)
    # list of 1 and 2

    append(list(1), list(2))
    # list of 1 and 2, not of 1 and list(2)

furthermore, "add elements to a vector" is misleading, since the
following works:

    append(data.frame(1), 2)
    # list of (named!) 1 and 2

    is.vector(data.frame(1))
    # FALSE

?c says:

"
Usage:
     c(..., recursive=FALSE)

Arguments:
     ...: objects to be concatenated.

recursive: logical.  If 'recursive = TRUE', the function recursively
          descends through lists (and pairlists) combining all their
          elements into a vector.

Details:
     The output type is determined from the highest type of the
     components in the hierarchy NULL < raw < logical < integer < real
     < complex < character < list < expression.  Pairlists are treated
     as lists, but non-vector components (such names and calls) are
     treated as one-element lists which cannot be unlisted even if
     'recursive = TRUE'.
"

this 'help' page explains what is supposed to happen when
recursive=TRUE, but it fails to tell you what is supposed to happen
when, by default, recursive=FALSE.  one might expect that it's to mean
that lists (and pairlists) are *not* recursively descended though, which
to my simple mind would mean that a list argument is taken to be a
single *element* of the result, not a collection of elements to be
included, each separately, in the result -- which is *not* the case, "of
course":

    c(list(1), 2)
    # list of 1 and 2, not a list of list(1) and 2

this 'help' page also explains that non-vector elements are treated as
one-element lists which cannot be unlisted -- even if recursive=TRUE
(!), but it does not really hold:

    c(1, data.frame(2,3))
    # list of 1, 2, and 3, not a list of 1 and data.frame(2,3)

    is.vector(data.frame(2,3))
    # FALSE

the subtle trick here is that data frames (which are lists) are
un-dataframed into lists that happen to be is.vector-TRUE (take care,
not all is.list-TRUE objects are is.vector-TRUE), hence are treated as
vectors though they are not.  (or maybe it's just that is.vector is
confused.)

vQ




More information about the R-help mailing list