【问题标题】:How can I prune these column ranges given another file in R?给定 R 中的另一个文件,如何修剪这些列范围?
【发布时间】:2016-10-04 02:25:11
【问题描述】:

我有一个 data.frame1 像:

1    bin chrom chromStart  chromEnd    name score
2     12  chr1   29123222  29454711 -5.7648   599
3    116  chr1   45799118  45986770 -4.8403   473
4    117  chr1   46327104  46490961 -5.3036   536
5    121  chr1   50780759  51008404 -4.4165   415
6    133  chr1   63634657  63864734 -4.8096   469
7    147  chr1   77825305  78062178 -5.4671   559

我也有一个 data.frame2 之类的:

  chrom chromStart chromEnd    N
1  chr1    63600000  63700000 1566
2  chr1    45800000  45900000 1566
3  chr1    29100000  29400000 1566
4  chr1    50400000  50500000 1566
5  chr1    46500000  46600000 1566

基本上,我在 data.frame1 中有从 chromStartchromEnd 的值范围。我想将这些范围缩小到仅与data.frame2 中的范围重叠的范围。例如,df1 的第一个范围是 2912322 到 29454711。我想将该范围缩减到 2912322 到 29400000,因为这是唯一与 df2 的范围重叠的范围。有谁知道我该怎么做?

我想要的输出是一个data.frame,比如:

    1    bin chrom chromStart  chromEnd    name score
    2     12  chr1   29123222  29400000 -5.7648   599
    3    116  chr1   45800000  45900000 -4.8403   473
    6    133  chr1   63634657  63700000 -4.8096   469

这是当前输出为我提供的 data.frame 的内容:

  chrom chromStart chromEnd bin    name score
1  chr1   29123222 29130000  12 -5.7648   599
2  chr1   29123222 29140000  12 -5.7648   599
3  chr1   29123222 29150000  12 -5.7648   599
4  chr1   29123222 29160000  12 -5.7648   599
5  chr1   29123222 29170000  12 -5.7648   599

【问题讨论】:

  • 如果 data.frame1 行是 1 到 9 并且范围 1 到 3 和 6 到 7 在 data.frame2 中会有什么行为?
  • 那么我希望保留范围 1 到 3 和范围 6 到 7。也许最好削减data.frame2?
  • 您可以将data.frame2中重叠的任何间隔合并到一个间隔中。然后通过此时的起点对您得到的区间列表进行排序,检查交点应该更容易。
  • 怎么做?
  • 你可以试试data.table::foverlapsIRanges::findOverlaps

标签: r dataframe


【解决方案1】:

+1 用于建议 IRanges::findOverlaps。

这是使用findOverlapsGenomicRanges 的解决方案:

library(GenomicRanges);

df1 <- cbind.data.frame(
    bin = c(12, 116, 117, 121, 133, 147),
    chrom = c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1"),
    chromStart = c(29123222, 45799118, 46327104, 50780759, 63634657, 77825305),
    chromEnd = c(29454711, 45986770, 46490961, 51008404, 63864734, 78062178),
    name = c(-5.7648, -4.8403, -5.3036, -4.4165, -4.8096, -5.4671),
    score = c(599, 473, 536, 415, 469, 559));

df2 <- cbind.data.frame(
    chrom = c("chr1", "chr1", "chr1", "chr1", "chr1"),
    chromStart = c(63600000, 45800000, 29100000, 50400000, 46500000),
    chromEnd = c(63700000, 45900000, 29400000, 50500000, 46600000),
    N = c(1566, 1566, 1566, 1566, 1566));

# Make GRanges objects from dataframes
gr1 <- with(df1, GRanges(
    chrom, 
    IRanges(start = chromStart, end = chromEnd), 
    bin = bin, 
    name = name, 
    score = score));

gr2 <- with(df2, GRanges(
    chrom,
    IRanges(start = chromStart, end = chromEnd),
    N = N));

# Get overlapping features
hits <- findOverlaps(query = gr1, subject = gr2);

# Get features from gr1 that overlap with features from gr2
idx1 <- queryHits(hits);
idx2 <- subjectHits(hits);
gr <- gr1[idx1];

# Make sure that we only keep the intersecting ranges
start(gr) <- ifelse(start(gr) >= start(gr2[idx2]), start(gr), start(gr2[idx2]));
end(gr) <- ifelse(end(gr) <= end(gr2[idx2]), end(gr), end(gr2[idx2]));

print(gr);

GRanges object with 3 ranges and 3 metadata columns:
      seqnames               ranges strand |       bin      name     score
         <Rle>            <IRanges>  <Rle> | <numeric> <numeric> <numeric>
  [1]     chr1 [29123222, 29400000]      * |        12   -5.7648       599
  [2]     chr1 [45800000, 45900000]      * |       116   -4.8403       473
  [3]     chr1 [63634657, 63700000]      * |       133   -4.8096       469
  -------
  seqinfo: 1 sequence from an unspecified genome; no seqlengths

# Turn GRanges into a dataframe
df <- data.frame(bin = mcols(gr)$bin, 
                 chrom = seqnames(gr), 
                 chromStart = start(gr), 
                 chromEnd = end(gr), 
                 name = mcols(gr)$name, 
                 score = mcols(gr)$score);
print(df);  

【讨论】:

  • 这接近我想要的,但它给了我很多,从 2912322 到 29300000、29400000、29500000。也可以在 data.frame 中获得这个输出吗?
  • 不确定您所说的“给我很多...”是什么意思。此方法尝试在 df2为 df1 中的每个特征 找到重叠区域。这不是你想要的吗?它重现了您在上面给出的示例。只需通过data.frame(chrom = seqnames(gr), chromStart = start(gr), chromEnd = end(gr), bin = mcols(gr)$bin, name = mcols(gr)$name, score = mcols(gr)$score) 即可获取数据框。
  • 我将您代码的输出放在我最近的编辑中。我只想在 df1 中修剪每个范围的最大范围
  • 恐怕我无法重现您编辑的输出。如果我从我的答案中运行代码,我会得到您似乎想要的输出,尽管它是 GRanges 对象而不是 data.frame。我已经编辑了我的答案以生成与原始帖子中的列顺序完全相同的 data.frame。请看一下,如果您仍然得到不同的东西,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多