@jdobres answer got me playing with the following examples, which helped me understand (kinda) what's going on.
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d$children <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d$children)
List of 2 # d$children is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
This works because the lhs and rhs of d$children <- add
are both lists with 2 items.
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d["children"] <- add
Warning message:
In `[<-.data.frame`(`*tmp*`, "children", value = list(list("Mary", :
provided 2 variables to replace 1 variables
> d
id name children
1 1 Jon Mary
2 2 Mark James
> str(d["children"])
'data.frame': 2 obs. of 1 variable: # d["children"] is 1 var. with 2 obs.
$ children:List of 2
..$ : chr "Mary"
..$ : chr "James"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
This doesn't work because the lhs of d$children <- add
is "1 var. with 2 obs." but the rhs is "a list of 2".
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> add <- list(list(list("Mary", "James"), list("Greta", "Sally")))
> d["children"] <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d["children"])
'data.frame': 2 obs. of 1 variable: # d["children"] is 1 var. with 2 obs.
$ children:List of 2
..$ :List of 2
.. ..$ : chr "Mary"
.. ..$ : chr "James"
..$ :List of 2
.. ..$ : chr "Greta"
.. ..$ : chr "Sally"
> str(add)
List of 1 # add is 1 list with 2 lists
$ :List of 2
..$ :List of 2
.. ..$ : chr "Mary"
.. ..$ : chr "James"
..$ :List of 2
.. ..$ : chr "Greta"
.. ..$ : chr "Sally"
The nomenclature is a little illogical here, but if you accept that a list has to be inside a list to count as a list, then the above works because the lhs of d$children <- add
is "1 var. with 2 obs." and the rhs is "1 list with 2 lists". Note the symmetry 1var:2lists::1list:2lists.
> d <- data.frame(id=1:2, name=c("Jon", "Mark"))
> d
id name
1 1 Jon
2 2 Mark
> add <- list(list("Mary", "James"), list("Greta", "Sally"))
> d[["children"]] <- add
> d
id name children
1 1 Jon Mary, James
2 2 Mark Greta, Sally
> str(d[["children"]])
List of 2 # d[["children"]] is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
> str(add)
List of 2 # add is a list of 2
$ :List of 2
..$ : chr "Mary"
..$ : chr "James"
$ :List of 2
..$ : chr "Greta"
..$ : chr "Sally"
Like the first example, this works because the lhs and rhs of d$children <- add
are both lists with 2 items.
I'm still not sure what the enclosing structure of add
should be called in the cases where str(add)
evaluates to List of 2...
, but that might not be important.