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
list
works withoutI
. Bothdata.frame
andDFrame
objects have an expectation that the resulting object should have equal numbers of rows. Alist
orSimpleList
can 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
DataFrame
says (bothSimpleList
andlist
have[
andlength
functions and respect drop = FALSE). I don't know about the technicalities of the implementation, so maybe Herve will provide details.