0

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.)

Zelbinian
  • 3,221
  • 5
  • 20
  • 23

1 Answers1

1

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.

Stewart Macdonald
  • 2,062
  • 24
  • 27
  • Yes, thank, you, although I'm not entirely sure why `frame[1,] <- c(1, list(c(2,5,7)), 3)` still does not work. – Zelbinian Apr 15 '17 at 04:10
  • What do you want `frame[1,] <- c(1, list(c(2,5,7)), 3)` to do? – Stewart Macdonald Apr 15 '17 at 04:23
  • It should give me 1 row in the data.frame with column 1 having a value "1", column 2 having a list of values "2, 5, 7", and column 3 having a value "3" – Zelbinian Apr 15 '17 at 05:24
  • I don't think you can mix a `list` with a `numeric` in the same vector. You can wrap the whole thing in a list as per my updated answer. – Stewart Macdonald Apr 15 '17 at 09:10
  • If this answer addressed your original question, you should mark it as answered. If you need more details about something else, consider asking a separate question. – Stewart Macdonald Apr 15 '17 at 09:14