Search code examples
rdplyrvcf-variant-call-format

Using %in% to filter rows based on Chromosome AND Position


I have two dataframes: one is VCF with genotype information, the other is a dataframe of "special" SNP positions. Using dplyr, I'd like to filter the VCF for only those positions that exist in the dataframe of special SNPs, however, I can't figure out how to use %in% for multiple columns.

VCF dataframe:

CHR   POS   REF   ALT
01    10    C     T
01    20    G     A
01    30    T     C
02    20    A     G
02    30    C     G
02    40    G     T
02    50    T     A

SPECIAL_SNP dataframe:

CHR   POS
01    20
01    30
02    40
02    50

Desired Output:

CHR   POS   REF   ALT
01    20    G     A
01    30    T     C
02    40    G     T
02    50    T     A

I was thinking something similar to this:

VCF %>%
    filter(.[, c("CHR", "POS"] %in% SPECIAL_SNP[, c("CHR", "POS")])

Thanks in advance for any help.


Solution

  • We can use inner_join

    library(dplyr)
    inner_join(VCF, SPECIAL_SNP)
    #   CHR POS REF ALT
    #1   1  20   G   A
    #2   1  30   T   C
    #3   2  40   G   T
    #4   2  50   T   A
    

    Or another option is %in%

    VCF[do.call(paste, VCF[1:2]) %in% do.call(paste, SPECIAL_SNP[1:2]),]
    

    data

    VCF <- structure(list(CHR = c(1L, 1L, 1L, 2L, 2L, 2L, 2L), POS = c(10L, 
    20L, 30L, 20L, 30L, 40L, 50L), REF = c("C", "G", "T", "A", "C", 
    "G", "T"), ALT = c("T", "A", "C", "G", "G", "T", "A")), 
      class = "data.frame", row.names = c(NA, 
    -7L))
    
    SPECIAL_SNP <- structure(list(CHR = c(1L, 1L, 2L, 2L), POS = c(20L, 30L, 40L, 
    50L)), class = "data.frame", row.names = c(NA, -4L))