2

我想将GenomicRanges::GRanges来自 Bioconductor 的对象作为单列存储在基础 Rdata.frame中。我想将它放在基础 R data.frame 中的原因是因为我想编写一些 ggplot2 函数,这些函数专门用于底层的 data.frames。但是,我所做的任何尝试似乎都没有结果。基本上这就是我想要做的:

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>

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

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

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

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

4

3 回答 3

3

我找到了一种将 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"
于 2021-04-14T00:39:24.797 回答
0

因此,自从发布这个问题以来,我发现我的问题的症结似乎在于 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 填充

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

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
于 2020-01-27T16:37:45.143 回答
0

一个不漂亮但实用的解决方案是使用 GenomicRanges 的访问器函数,然后转换为相关的数据向量,即数字或字符。我添加了 magrittr,但你也可以不使用它。

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
于 2019-12-17T16:31:03.013 回答