首页 文章

R:根据来自另一个data.table的条件“标记”一行

提问于
浏览
1

我有一个超过100,000行的data.table(A) . 共有3列 .

chrom start end 1: chr1 6484847 6484896 2: chr1 6484896 6484945 3: chr1 6484945 6484994 4: chr1 6484994 6485043 5: chr1 6485043 6485092 --- 183569: chrX 106893605 106893654 183570: chrX 106893654 106893703 183571: chrX 106893703 106893752 183572: chrX 106893752 106893801 183573: chrX 106893801 106894256

我想生成一个名为“gene”的新列,它为来自另一个data.table的每个行提供一个标签,该行有~90行(B) . 见如下:

chrom start end gene 1: chr1 6484847 6521004 ESPN 2: chr1 41249683 41306124 KCNQ4 3: chr1 55464616 55474465 BSND 42: chrX 82763268 82764775 POU3F4 43: chrX 100600643 100603957 TIMM8A 44: chrX 106871653 106894256 PRPS1

如果data.table A中的行起始值在data.table B的行开始值和结束值内,则需要A中的行相应地标记正确的基因 .

例如,得到的完整data.table A将是

chrom start end gene 1: chr1 6484847 6484896 ESPN 2: chr1 6484896 6484945 ESPN 3: chr1 6484945 6484994 ESPN 4: chr1 6484994 6485043 ESPN 5: chr1 6485043 6485092 ESPN --- 183569: chrX 106893605 106893654 TIMM8A 183570: chrX 106893654 106893703 TIMM8A 183571: chrX 106893703 106893752 TIMM8A 183572: chrX 106893752 106893801 TIMM8A 183573: chrX 106893801 106894256 TIMM8A

我已经尝试了一些嵌套循环来做到这一点,但这似乎需要花费太长时间 . 我认为必须有一种方法来使用data.table包,但我似乎无法弄明白 .

任何和所有建议将不胜感激 .

2 回答

  • 1

    虽然在基础R中可以做到这一点(或者可能使用 data.table ),但我强烈建议使用 GenomicRanges ;它's a very powerful and flexible R/Bioconductor library that'是为这类任务而设计的 .

    以下是使用 GenomicRanges::findOverlaps 的示例:

    # Sample data
    df1 <- read.table(text =
        "chrom     start      end
         chr1   6484847   6484896
         chr1   6484896   6484945
         chr1   6484945   6484994
         chr1   6484994   6485043
         chr1   6485043   6485092", sep = "", header = T, stringsAsFactors = F);
    
    df2 <- read.table(text =
        "chrom     start       end     gene
         chr1   6484847   6521004     ESPN
         chr1  41249683  41306124     KCNQ4
         chr1  55464616  55474465     BSND
         chrX  82763268  82764775     POU3F4
         chrX 100600643 100603957     TIMM8A
         chrX 106871653 106894256     PRPS1", sep = "", header = TRUE, stringsAsFactors = F);
    
    # Convert to GRanges objects
    gr1 <- with(df1, GRanges(chrom, IRanges(start = start, end = end)));
    gr2 <- with(df2, GRanges(chrom, IRanges(start = start, end = end), gene = gene));
    
    # Find features from gr1 that overlap with gr2
    m <- findOverlaps(gr1, gr2);
    
    # Add gene annotation as metadata to gr1
    mcols(gr1)$gene[queryHits(m)] <- mcols(gr2)$gene[subjectHits(m)];
    gr1;
    #GRanges object with 5 ranges and 1 metadata column:
    #      seqnames             ranges strand |        gene
    #         <Rle>          <IRanges>  <Rle> | <character>
    #  [1]     chr1 [6484847, 6484896]      * |        ESPN
    #  [2]     chr1 [6484896, 6484945]      * |        ESPN
    #  [3]     chr1 [6484945, 6484994]      * |        ESPN
    #  [4]     chr1 [6484994, 6485043]      * |        ESPN
    #  [5]     chr1 [6485043, 6485092]      * |        ESPN
    #  -------
    #  seqinfo: 1 sequence from an unspecified genome; no seqlengths
    
  • 4

    除了GRanges/IRanges solution by Maurits Evers之外,还有一种替代 data.table 方法,在连接时使用非equi连接和更新 .

    A[B, on = .(chrom, start >= start, start <= end), gene := i.gene][]
    

    chrom起始末端基因
    1:chr1 6484847 6484896 ESPN
    2:chr1 6484896 6484945 ESPN
    3:chr1 6484945 6484994 ESPN
    4:chr1 6484994 6485043 ESPN
    5:chr1 6485043 6485092 ESPN
    6:chrX 106893605 106893654 PRPS1
    7:chrX 106893654 106893703 PRPS1
    8:chrX 106893703 106893752 PRPS1
    9:chrX 106893752 106893801 PRPS1
    10:chrX 106893801 106894256 PRPS1

    根据OP, AB 已经是 data.table 个对象 . 因此,这种方法避免了对对象的强制 .

    可重复数据

    library(data.table)
    A <- fread("rn         chrom     start      end 
         1:  chr1   6484847   6484896 
         2:  chr1   6484896   6484945 
         3:  chr1   6484945   6484994 
         4:  chr1   6484994   6485043 
         5:  chr1   6485043   6485092
    183569:  chrX 106893605 106893654
    183570:  chrX 106893654 106893703
    183571:  chrX 106893703 106893752
    183572:  chrX 106893752 106893801
    183573:  chrX 106893801 106894256", drop = 1L)
    
    B <- fread("rn    chrom     start       end     gene
     1:  chr1   6484847   6521004     ESPN
     2:  chr1  41249683  41306124     KCNQ4
     3:  chr1  55464616  55474465     BSND
    42:  chrX  82763268  82764775     POU3F4
    43:  chrX 100600643 100603957     TIMM8A
    44:  chrX 106871653 106894256     PRPS1", drop = 1L)
    

相关问题