r语言 - GRanges 作为 base::d ata.frame 中的列



我想将Bioconductor的GenomicRanges::GRanges对象作为单列存储在基本Rdata.frame中。我想把它放在一个基本的R data.frame中的原因是因为我想编写一些专门处理data.frame的ggplot2函数。然而,我所做的任何尝试似乎都没有成果。基本上这就是我想做的:

library(GenomicRanges)
x <- GRanges(c("chr1:100-200", "chr1:200-300"))
df <- data.frame(x = x, y = 1:2)

但是该列会自动扩展,而我喜欢将其保留为单个列中的有效GRanges对象:

> df
x.seqnames x.start x.end x.width x.strand y
1       chr1     100   200     101        * 1
2       chr1     200   300     101        * 2

当我使用S4Vectors::DataFrame时,它可以按照我想要的方式工作,除了我希望一个基本的 R data.frame 做同样的事情:

> S4Vectors::DataFrame(x = x, y = 1:2)
DataFrame with 2 rows and 2 columns
x         y
<GRanges> <integer>
1 chr1:100-200         1
2 chr1:200-300         2

我也尝试了以下方法,但没有成功:

> df <- data.frame(y = 1:2)
> df[["x"]] <- x
> df
y                                                           x
1 1 <S4 class ‘GRanges’ [package “GenomicRanges”] with 7 slots>
2 2                                                        <NA>

警告消息: In format.data.frame(if (omit( x[seq_len(n0(, , drop = FALSE] else x, : 损坏的数据框:列将被截断或填充 NA

df[["x"]] <- I(x)

rep(value, length.out = nrows( 中的错误: 尝试复制类型为"S4"的对象

我在使用vctrs::new_rcrd实现 GRanges 类的 S3 变体时取得了一些小的成功,但这似乎是一种非常迂回的方法,可以获得代表基因组范围的单个列。

我找到了一种非常简单的将 GR 对象转换为数据帧的方法,以便您可以非常轻松地对 data.frame 进行操作。Repitools包中的annoGR2DF函数可以做到这一点。

> library(GenomicRanges)
> library(Repitools)
> 
> x <- GRanges(c("chr1:100-200", "chr1:200-300"))
> 
> df <- annoGR2DF(x)
> df
chr start end width
1 chr1   100 200   101
2 chr1   200 300   101
> class(df)
[1] "data.frame"

一个不漂亮但实用的解决方案是使用GenomicRanges的访问器函数,然后转换为相关的数据向量,即数字或字符。我添加了马格里特,但你也可以在没有它的情况下做到这一点。

library(GenomicRanges)
library(magrittr)
x <- GRanges(c("chr1:100-200", "chr1:200-300"))
df <- data.frame(y = 1:2)
df$chr <- seqnames(x) %>% as.character
df$start <- start(x) %>% as.numeric
df$end <- end(x) %>% as.numeric
df$strand <- strand(x) %>% as.character
df$width <- width(x) %>% as.numeric
df

因此,自从发布这个问题以来,我发现问题的关键似乎是S4对象的格式方法不能很好地与data.frames配合使用,并且将GRanges作为列不一定是问题。(不过,data.frame的构造仍然是(。

考虑一下原始问题的这一部分:

> df <- data.frame(y = 1:2)
> df[["x"]] <- x
> df
y                                                           x
1 1 <S4 class ‘GRanges’ [package “GenomicRanges”] with 7 slots>
2 2   

警告消息:在 format.data.frame(if (omit( x[seq_len(n0(, , drop = FALSE] else x, : 损坏的数据帧中: 列将被截断或填充 NA

如果我们为 GRanges 编写一个简单的格式方法,它不会抛出错误:

library(GenomicRanges)
format.GRanges <- function(x, ...) {showAsCell(x)}
df <- data.frame(y = 1:3)
df$x <- GRanges(c("chr1:100-200", "chr1:200-300", "chr2:100-200"))
> df
y            x
1 1 chr1:100-200
2 2 chr1:200-300
3 3 chr2:100-200

它似乎也很好:

> df[c(1,3),]
y            x
1 1 chr1:100-200
3 3 chr2:100-200

作为奖励,这似乎也适用于其他 S4 类,例如:

library(S4Vectors)
format.Rle <- function(x, ...) {showAsCell(x)}
x <- Rle(1:5, 5:1)
df <- data.frame(y = 1:15)
df$x <- x

最新更新