2014-06-15 141 views
6

我努力尝试将来自两个文件的部分匹配字符串组合在一起。合并部分匹配的字符串

文件1包含一个唯一字符串列表。这些字符串部分匹配的数量在文件2串如何合并文件1行与文件2每个匹配的情况下

文件1

mmu-miR-677-5p_MIMAT0017239 
mmu-miR-181a-1-3p_MIMAT0000660 

文件2

mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA 
mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT 
mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT 
mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC 
mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC 

期望的输出

mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA 
mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT 
mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT 
mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC 
mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC 

我已经尝试在R,b中使用pmatch()不要误会。我看起来像perl会处理?

也许是这样的:

perl -ne'exec q;perl;, "-ne", q $print (/\Q$.$1.q;/?"$. YES":$. .q\; NO\;);, "file2" if m;^(.*)_pat1;' file1 

回答

4

这是一个简短的Perl溶液,将其从在哈希file1保存所有的数据,然后检索它作为file2被扫描

use strict; 
use warnings; 
use autodie; 

my @files = qw/ file1.txt file2.txt /; 

my %file1 = do { 
    open my $fh, '<', $files[0]; 
    map /([^_]+)_(\S+)/, <$fh>; 
}; 

open my $fh, '<', $files[1]; 
while (<$fh>) { 
    my ($key) = /([^_]+)/; 
    printf "%-32s%s", "${key}_$file1{$key}", $_; 
} 

输出

mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA 
mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT 
mmu-miR-677-5p_MIMAT0017239  mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT 
mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC 
mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC 
3

当然,你可以做到这一点在R.事实上,pmatch荷兰国际集团整个字符串不会给你想要的结果 - 你必须匹配相应的字符串。

我假设在文件1中第一个标识符是677而不是667,否则很难猜测匹配方案(我假设你的例子只是一个更大的数据库的一部分)。

file1 <- readLines(textConnection('mmu-miR-677-5p_MIMAT0017239 
mmu-miR-181a-1-3p_MIMAT0000660')) 

file2 <- readLines(textConnection('mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA 
mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT 
mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT 
mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC 
mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC')) 

library(stringi) 
file1_id <- stri_extract_first_regex(file1, "^.*?(?=_)") 
file2_id <- stri_extract_first_regex(file2, "^.*?(?=_)") 

cbind(file1=file1[match(file2_id, file1_id)], file2=file2) 
##  file1       file2          
## [1,] "mmu-miR-677-5p_MIMAT0017239" "mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA" 
## [2,] "mmu-miR-677-5p_MIMAT0017239" "mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT" 
## [3,] "mmu-miR-677-5p_MIMAT0017239" "mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT" 
## [4,] "mmu-miR-181a-1-3p_MIMAT0000660" "mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC" 
## [5,] "mmu-miR-181a-1-3p_MIMAT0000660" "mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC" 
+0

当我从CSV文件中读取抱怨STR不是一个特征向量( “?^ *(= _)” 文件1)在stri_extract_first_regex错误: 说法'str'应该是一个字符向量(或者一个强制对象) – user3741035

+0

也许你应该使用'readLines'呢? – gagolews

+1

@ user3741035你应该至少尝试在匹配它们之前阅读文件。这里的答案假设你有基本的读/写R文件。 – agstudy

2

您可以通过agrep进行模糊搜索。你应该玩遥远的距离。在这里,我手动修复它11

基本上我这样做是为了提取出每个单词文件1匹配的行数:

sapply(file1,agrep,file2,max=11) 
$`mmu-miR-677-5p_MIMAT0017239` 
[1] 1 2 3 

$`mmu-miR-181a-1-3p_MIMAT0000660` 
[1] 4 5 

为了得到一个data.frame结果:

do.call(rbind, 
    lapply(file1, 
     function(x) 
     data.frame(file1=x, 
        file2=agrep(x,file2,max=11,value=T)))) 


         file1         file2 
1 mmu-miR-677-5p_MIMAT0017239 mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGA 
2 mmu-miR-677-5p_MIMAT0017239 mmu-miR-677-5p_CTTCAGTGATGATTAGCTTCTGACT 
3 mmu-miR-677-5p_MIMAT0017239 mmu-miR-677-5p_TTCAGTGATGATTAGCTTCTGACT 
4 mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTAC 
5 mmu-miR-181a-1-3p_MIMAT0000660 mmu-miR-181a-1-3p_ACCATCGACCGTTGATTGTACC 
+0

它抱怨我的输入文件中的行数不同:'警告消息: 在agrep(x,file2,max = 11,value = T)中: 参数'pattern'的长度> 1,只有第一个元素是使用 错误在do.call(rbind,lapply(file1,function(x)data.frame(file1 = x,: )在为函数'do.call'选择方法时评估参数'args'时出错:错误data.frame(file1 = x,file2 = agrep(x,file2,max = 11,value = T)): 参数表示行数不同:1908,0' – user3741035

+0

@ user3741035当您尝试使用gagolews答案中提供的数据'file1'和'file2'时,您得到了什么? – agstudy