2014-06-15 11 views
6

Ich habe Probleme mit dem Versuch, teilweise übereinstimmende Zeichenfolgen aus zwei Dateien zu kombinieren.Merge teilweise übereinstimmende Zeichenfolgen

Datei 1 enthält eine Liste eindeutiger Zeichenfolgen. Diese Strings werden teilweise abgestimmt auf eine Anzahl von Strings in Datei 2. Wie fusionieren ich die Zeilen in der Datei 1 mit Datei 2 für jeden Fall angepasst

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 

gewünschter Ausgang

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 

I hat versucht pmatch() in R verwendet wird, b Aber mach es nicht richtig. Ich sehe aus wie etwas, mit dem Perl umgehen würde ??

Vielleicht so etwas wie folgt aus:

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

Antwort

4

Dies ist eine kurze Perl-Lösung, die aus einem Hash file1 in alle Daten speichert und ruft es dann als file2 wird

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

Ausgang

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

Natürlich kann man es in der Tat in R. tun kann, pmatch ing ganze Strings werden Sie nicht das gewünschte Ergebnis - Sie haben entsprechende Teil übereinstimmen.

Ich nehme an, dass in Datei 1 der erste Bezeichner 677 und nicht 667 ist, sonst ist es schwer das passende Schema zu erraten (ich nehme an, dass Ihr Beispiel nur ein Teil einer größeren Datenbank ist).

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

, wenn ich von meiner CSV-Datei lesen klagt es über str kein Zeichen Vektor ist: ("?^* (= _)" File1,) Fehler bei stri_extract_first_regex: Argument 'str' sollte ein Zeichenvektor sein (oder ein Objekt, auf das ein Objekt erzwungen werden kann) – user3741035

+0

Vielleicht solltest du' readLines' dafür benutzen? – gagolews

+1

@ user3741035 Sie sollten zumindest versuchen, Dateien zu lesen, bevor sie übereinstimmen. Die Antworten hier gehen davon aus, dass Sie das Grundlegende zum Lesen/Schreiben von R-Dateien haben. – agstudy

2

Sie können agrep für Fuzzy-Suche. Du solltest mit Distanz spielen. Hier habe ich es manuell bin Festsetzung 11.

Im Grunde mache ich das Linien-Nummer zu extrahieren, die jedes Wort in file1 Spiele:

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

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

Um das Ergebnis eines data.frame zu erhalten:

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

Es beschwert sich über die unterschiedliche Anzahl von Zeilen in meinen Imput-Dateien: 'Warnmeldung: In agrep (x, file2, max = 11, Wert = T): Argument' Muster 'hat Länge> 1 und nur das erste Element wird used Fehler in do.call (rbind, lapply (Datei1, Funktion (x) data.frame (file1 = x,: Fehler bei der Auswertung des Arguments 'args' bei der Auswahl einer Methode für die Funktion 'do.call'): Fehler in data.frame (file1 = x, file2 = agrep (x, file2, max = 11, Wert = T)): Argumente implizieren unterschiedliche Anzahl von Zeilen: 1908, 0 ' – user3741035

+0

@ user3741035 Was hast du bekommen, wenn du mit den Dateien 'file1' und' file2' in der Antwort von gagolews probierst? – agstudy

Verwandte Themen