Reputation: 3407
Create a data.frame where a column is a list
^ this got me most of the way there, but there are significant hurdles I can't seem to clear.
Pretend frame
is a data.frame of 3 columns with the middle column intended to be a list. This works:
frame[1,]$list_column <- list(1:4)
None of this works:
frame[1,] <- c(1, list(1:4), 3)
frame[1,] <- c(1, I(list(1:4)), 3)
frame[1,]$list_column <- list(1,3,5)
frame[1,]$list_column <- I(list(1,3,5))
In all cases R thinks I'm trying to add multiple things to a bucket that holds 1 thing and I don't know how to tell it otherwise. (And, btw, that last one is the thing I'd really like to do.)
Upvotes: 0
Views: 539
Reputation: 2142
The key is in creating your list correctly:
> list(1:4)
[[1]]
[1] 1 2 3 4
# Produces a list that contains a single vector
> list(1:4, 7:9)
[[1]]
[1] 1 2 3 4
[[2]]
[1] 7 8 9
# Produces a list that contains two separate vectors
> list(c(1:4, 7:9))
[[1]]
[1] 1 2 3 4 7 8 9
# Produces a list that contains a single vector
So you could do something like this:
frame <- data.frame(a=1:3)
frame$list_column <- NA
frame[1,]$list_column <- list(c(1, 3, 5))
frame[2,]$list_column <- list(1:5)
frame[3,]$list_column <- list(c(1:3, 5:9))
print(frame)
a list_column
1 1 1, 3, 5
2 2 1, 2, 3, 4, 5
3 3 1, 2, 3, 5, 6, 7, 8, 9
str(frame)
'data.frame': 3 obs. of 2 variables:
$ a : int 1 2 3
$ list_column:List of 3
..$ : num 1 3 5
..$ : int 1 2 3 4 5
..$ : int 1 2 3 5 6 7 8 9
Is that what you're after?
Update to address your other query:
frame <- data.frame(a=rep(NA, 3), b=NA, c=NA)
frame[1,] <- list(list(1), list(c(2,5,7)), list(3))
When you're getting unexpected results, have a look at the structure of the object you're dealing with:
> str(c(1, list(c(2,5,7)), 3))
List of 3
$ : num 1
$ : num [1:3] 2 5 7
$ : num 3
This shows that the second element in the list is a vector with 3 items. If you try to put that into a data frame cell, you'll get an error:
> frame <- data.frame(a=rep(NA, 3), b=NA, c=NA)
> frame[1,] <- c(1, list(c(2,5,7)), 3)
Warning message:
In `[<-.data.frame`(`*tmp*`, 1, , value = list(1, c(2, 5, 7), 3)) :
replacement element 2 has 3 rows to replace 1 rows
This is telling you the number of elements don't match the number of slots in your data frame.
Upvotes: 1