2014-06-15 10 views
6

Sono in difficoltà con il tentativo di combinare stringhe parzialmente abbinate da due file.unione di stringhe con corrispondenza parziale

Il file 1 contiene un elenco di stringhe univoche. Queste stringhe sono parzialmente abbinate a una serie di stringhe in file 2. Come faccio a fondere le righe nel file 1 con il file 2 per ogni caso abbinato

File1

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

File2

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 

uscita desiderata

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 

ho provato con pmatch() in R, b Non è giusto. Mi sembra che qualcosa perl possa gestire ??

Forse qualcosa di simile:

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

risposta

4

questa è una soluzione breve Perl, che salva tutti i dati da file1 in un hash e poi recupera come file2 viene analizzato

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}", $_; 
} 

uscita

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

Naturalmente si può fare in R. In effetti, pmatch ing stringhe intere non vi darà il risultato desiderato - hai avuto modo di abbinare sottostringhe appropriate.

Suppongo che nel file 1 il primo identificatore sia 677 e non 667, altrimenti è difficile indovinare lo schema di corrispondenza (presumo che il tuo esempio sia solo una parte di un database più grande).

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

quando ho letto dal mio file CSV si lamenta str non essere un vettore di carattere: ("??^* (= _)" File1,) Errore in stri_extract_first_regex: argomento 'str' dovrebbe essere un vettore di caratteri (o un oggetto coercibile a) – user3741035

+0

Forse dovresti usare' readLines' per quello? – gagolews

+1

@ user3741035 dovresti almeno provare a leggere i file prima di abbinarli. Le risposte qui presuppongono che tu abbia la base per leggere/scrivere i file R. – agstudy

2

Si può agrep per ricerca fuzzy. Dovresti giocare con la distanza. Qui sto riparando manualmente a 11.

Fondamentalmente sto facendo questo per estrarre il numero righe quello che soddisfa ogni parola in file1:

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

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

per ottenere il risultato di un 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

Si lamenta del diverso numero di righe nei miei file di imput: 'Messaggio di avviso: In agrep (x, file2, max = 11, valore = T): l'argomento' pattern 'ha lunghezza> 1 e solo il primo elemento sarà utilizzato Errore in do.call (rbind, lapply (file1, funzione (x) data.frame (file1 = x,: errore nel valutare l'argomento 'args' nella selezione di un metodo per la funzione 'do.call': Errore in data.frame (file1 = x, file2 = agrep (x, file2, max = 11, valore = T)): gli argomenti implicano un numero diverso di righe: 1908, 0 ' – user3741035

+0

@ user3741035 cosa hai ottenuto quando provi con i dati 'file1' e' file2' forniti nella risposta di gagolews? – agstudy

Problemi correlati