DataFrame Construction With Non-standard Column
1
0
Entering edit mode
Dario Strbenac ★ 1.5k
@dario-strbenac-5916
Last seen 2 days ago
Australia

Why does one fail but the other succeeds?

> DataFrame(ID = LETTERS[1:3], score = list(2:4, 6, 7:8))
Error in DataFrame(ID = LETTERS[1:3], score = list(2:4, 6, 7:8)) : 
  cannot coerce class "list" to a DataFrame
> data <- DataFrame(ID = LETTERS[1:3])
> data$score <- list(2:4, 6, 7:8)
> data
DataFrame with 3 rows and 2 columns
           ID  score
  <character> <list>
1           A  2,3,4
2           B      6
3           C    7,8
S4Vectors • 1.0k views
ADD COMMENT
3
Entering edit mode
@herve-pages-1542
Last seen 13 hours ago
Seattle, WA, United States

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.

ADD COMMENT
0
Entering edit mode

Out of interest, SimpleList() works without I(), why is that?

ADD REPLY
0
Entering edit mode

Same reason that list works without I. Both data.frame and DFrame objects have an expectation that the resulting object should have equal numbers of rows. A list or SimpleList can contain anything in each list item.

ADD REPLY
0
Entering edit mode
suppressMessages(library(S4Vectors))

DataFrame(ID = LETTERS[1:3], score = list(2:4, 6, 7:8))
#> Error in DataFrame(ID = LETTERS[1:3], score = list(2:4, 6, 7:8)): cannot coerce class "list" to a DataFrame

DataFrame(ID = LETTERS[1:3], score = SimpleList(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
Created on 2023-09-25 by the reprex package (v2.0.1)
ADD REPLY
2
Entering edit mode

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:

library(GenomicRanges)

grl <- GRangesList(GRanges("chr1", IRanges(1, 4:6)),
                   GRanges(),
                   GRanges("chr2", IRanges(5, 9:8)))

is(grl, "List")
# [1] TRUE

DataFrame(ID = LETTERS[1:3], region=grl)
# DataFrame with 3 rows and 2 columns
#            ID                     region
#   <character>              <GRangesList>
# 1           A chr1:1-4,chr1:1-5,chr1:1-6
# 2           B                           
# 3           C          chr2:5-9,chr2:5-8
ADD REPLY
0
Entering edit mode

Oh, ok. I understand. Technically both should work according to what the help page for DataFrame says (both SimpleList and list have [ and length functions and respect drop = FALSE). I don't know about the technicalities of the implementation, so maybe Herve will provide details.

ADD REPLY

Login before adding your answer.

Traffic: 726 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6