You need to protect the list by wrapping it in I(), otherwise the DataFrame() constructor interprets it as a list of 3 columns (so it tries to turn it into a DataFrame and fails because the columns don't have the same length):
library(S4Vectors)
DataFrame(ID = LETTERS[1:3], score = I(list(2:4, 6, 7:8)))
DataFrame with 3 rows and 2 columns
# ID score
# <character> <list>
# 1 A 2,3,4
# 2 B 6
# 3 C 7,8
Note that this is no different from what happens with ordinary data frames:
data.frame(ID = LETTERS[1:3], score = list(2:4, 6, 7:8))
# Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :
# arguments imply differing number of rows: 3, 1, 2
data.frame(ID = LETTERS[1:3], score = I(list(2:4, 6, 7:8)))
# ID score
# 1 A 2, 3, 4
# 2 B 6
# 3 C 7, 8
If you don't protect, data.frame() and DataFrame() want to interpret the list as a list of columns (so 3 columns in this case):
data.frame(ID = LETTERS[1:3], score = list(A=2:4, B=letters[1:3], C=7:9))
# ID score.A score.B score.C
# 1 A 2 a 7
# 2 B 3 b 8
# 3 C 4 c 9
DataFrame(ID = LETTERS[1:3], score = list(A=2:4, B=letters[1:3], C=7:9))
# DataFrame with 3 rows and 4 columns
# ID score.A score.B score.C
# <character> <integer> <character> <integer>
# 1 A 2 a 7
# 2 B 3 b 8
# 3 C 4 c 9
Best,
H.
Out of interest,
SimpleList()works withoutI(), why is that?Same reason that
listworks withoutI. Bothdata.frameandDFrameobjects have an expectation that the resulting object should have equal numbers of rows. AlistorSimpleListcan contain anything in each list item.SimpleList is a List derivative and List derivatives in general don't need protection. For example, a GRangesList object (which is also a List derivative) does not need protection either:
Oh, ok. I understand. Technically both should work according to what the help page for
DataFramesays (bothSimpleListandlisthave[andlengthfunctions and respect drop = FALSE). I don't know about the technicalities of the implementation, so maybe Herve will provide details.