我试图找到一种优雅的方法来查找数据框中两个字符列之间的匹配。复杂的部分是,任何一个字符串都可以包含一个逗号分隔的列表,如果一个列表的成员与另一个列表的任何成员匹配,那么整个条目都将被视为匹配。我不确定我解释得有多好,所以这里是示例数据和输出:
备选1:
- AT
- A
- G
- CGTCC、AT
- CGC
Alt2:
- AA
- A
- GG
- AT、GGT
- 共格
每行的预期匹配:
- 第1行=无
- 第2行= A
- 第3行=无
- 第4行= AT
- 第5行=无
非工作溶液:
首次尝试:按所需列合并整个数据框,然后匹配上面显示的alt列:
match1 = data.frame(merge(vcf.df, ref.df, by=c("chr", "start", "end", "ref")))
matches = unique(match1[unlist(sapply(match1$Alt1 grep, match1$Alt2, fixed=TRUE)),])
第二种方法,使用来自VariantAnnoatation/Granges的findoverlaps特征:
findoverlaps(ranges(vcf1), ranges(vcf2))
任何建议将不胜感激!谢谢!
解决方案感谢@马拉特Talipov在下面的回答,下面的解决方案可以比较两个逗号分隔的字符串:
> ##read in edited kaviar vcf and human ref
> ref <- readVcfAsVRanges("ref.vcf.gz", humie_ref)
Warning message:
In .vcf_usertag(map, tag, ...) :
ScanVcfParam ‘geno’ fields not present: ‘AD’
> ##rename chromosomes to match with vcf files
> ref <- renameSeqlevels(ref, c("1"="chr1"))
> ##################################
> ## Gather VCF files to process ##
> ##################################
> ##data frame *.vcf.gz files in directory path
> vcf_path <- data.frame(path=list.files(vcf_dir, pattern="*.vcf.gz$", full=TRUE))
> ##read in everything but sample data for speediness
> vcf_param = ScanVcfParam(samples=NA)
> vcf <- readVcfAsVRanges("test.vcf.gz", humie_ref, param=vcf_param)
> #################
> ## Match SNP's ##
> #################
> ##create data frames of info to match on
> vcf.df = data.frame(chr =as.character(seqnames(vcf)), start = start(vcf), end = end(vcf), ref = as.character(ref(vcf)),
+ alt=alt(vcf), stringsAsFactors=FALSE)
> ref.df = data.frame(chr =as.character(seqnames(ref)), start = start(ref), end = end(ref),
+ ref = as.character(ref(ref)), alt=alt(ref), stringsAsFactors=FALSE)
>
> ##merge based on all positional fields except vcf
> col_match = data.frame(merge(vcf.df, ref.df, by=c("chr", "start", "end", "ref")))
> library(stringi)
> ##split each alt column by comma and bind together
> M1 <- stri_list2matrix(sapply(col_match$alt.x,strsplit,','))
> M2 <- stri_list2matrix(sapply(col_match$alt.y,strsplit,','))
> M <- rbind(M1,M2)
> ##compare results
> result <- apply(M,2,function(z) unique(na.omit(z[duplicated(z)])))
> ##add results column to col_match df for checking/subsetting
> col_match$match = result
> head(col_match)
chr start end ref alt.x alt.y match
1 chr1 39998059 39998059 A G G G
2 chr1 39998059 39998059 A G G G
3 chr1 39998084 39998084 C A A A
4 chr1 39998084 39998084 C A A A
5 chr1 39998085 39998085 G A A A
6 chr1 39998085 39998085 G A A A
4条答案
按热度按时间uqzxnwby1#
如果输入列表的长度相等,并且您希望以成对的方式比较列表元素,则可以使用以下解决方案:
样品输入:
输出:
iyfjxgzm2#
继续使用
stringi
包,您可以使用马拉特的答案中的Alt1
和Alt2
数据执行类似的操作。或者在R中,我们可以使用
scan()
来用逗号分隔字符串。bvjxkvbb3#
你可以这样做:
ubbxdtey4#
示例 Dataframe
查找匹配值的函数
将函数应用到列中,并将结果存储在新列中
查看结果