Frage:
Bereichsüberlappungspythonfehler mit genomischen Regionen
novicebioinforesearcher
2017-06-21 00:26:57 UTC
view on stackexchange narkive permalink

Ich habe zwei Dateien

  s3.txt: 1 10 201 5 202 20 302 25 301 10 502 20 601 14 17s4.txt: 1 10 202 20 30  

Ich versuche, col0 beider Dateien abzugleichen und Zeilen zu erhalten, die zwischen dem Bereich (einschließlich ihrer selbst) 10-20 und 20-30 liegen, wie in s4 gezeigt. file.file s4 hat Koordinaten, die als verwendet werden können Referenzbereich (Chrom Anfang und Ende) und s3 enthält eine Liste von Koordinaten aus einer experimentellen Bedingung. Ich versuche zu erreichen, auf welche Koordinaten aus meiner Datei s3 auf oder zwischen meine Referenzkoordinaten in s4 fallen.

bisheriger Code:

  enthält_ranges = [] mit open ('s4.txt', 'r') als f: für Zeile in f: fields = Zeile. strip (). split ('\ t') enthält_ranges.append (Felder) getestete_ranges = [] mit open ('s3.txt', 'r') als f: für Zeile in f: fields = line.strip (). split ('\ t') testing_ranges.append (Felder) für c_range in enthaltenden Bereichen: für t_range in getesteten Bereichen: tst = int (t_range [1]) ten = int (t_range [2]) cst = int (c_range [1]) cen = int (c_range [2]) wenn c_range [0] == t_range [0]: eingeschlossen = cst > = tst und cen < = zehn wenn enthalten == True: print t_range  

Ausgabe mit fehlender Zeile (1 14 17):

  ['1', '10', '20'] ['1', '5', '20'] ['1 ',' 10 ',' 50 '] [' 2 ',' 20 ',' 30 '] [' 2 ',' 20 ',' 60 ']  

Gewünschte Ausgabe:

  1 10 202 20 302 25 301 14 17  

Ich bin mir nicht sicher, ob meine Logik falsch ist und warum 14-17 als i fehlt t liegt zwischen 10-20

  [EDIT] unter Verwendung von pybedtools>>> print (s4.intersect (s3, wb = True)) 1 10 20 1 10 201 10 20 1 5 201 10 20 1 10 501 14 17 1 14 172 20 30 2 20 302 25 30 2 25 302 20 30 2 20 60>>> print (s4.intersect (s3, wa = True, wb = True, F = 1)) 1 10 20 1 10 201 10 20 1 14 172 20 30 2 20 30
2 20 30 2 25 30 Verwenden von Bedops bin $ less answer.bed 1 5 201 10 201 10 501 14 172 20 302 20 602 25 30 Verwenden von @ bli-Code (auf Python2.7) ('1', 10, 20) ('1') , 14, 17) ('2', 20, 30) ('2', 25, 30) Warum kann ich das Intervall 1 5 20  
nicht sehen?
Welches Ergebnis erzielen Sie mit `bedops --element-of`?
Bitte bringen Sie Ihre Logik- / Codierungsfragen zu Stack Overflow. Das Verhältnis Ihrer Frage zum Thema Bioinformatik ist nur zufällig.
@RobertC Wenn OP ein "Bett" -Tag hinzufügt, sieht diese Frage sofort wie eine Bioinformatik-Frage aus. Siehe auch die Antworten. OP wird hier viel eher solche Antworten erhalten. Diese Frage könnte sicherlich verbessert werden, ist aber nicht vom Thema abweichend.
Verwenden Sie einfach Bedops, wie angegeben. Die Verwendung von Wrappern für Befehlszeilentools ist selten ein Ersatz für das Erlernen der Tools.
Können Sie bitte mehr Geschichte / Kontext zu dieser Frage hinzufügen? Es sieht aus wie eine reine Programmierfrage (vermutlich, warum es als nicht zum Thema gehörend markiert wurde). Es wäre schön, wenn Sie erklären könnten, was die verschiedenen Zahlen bedeuten und warum Sie dies tun möchten.
Sie sollten aussagekräftigere Namen für Ihre Variablen verwenden. Dies würde das Lesen des Codes für andere, aber auch für Sie erleichtern.
Anscheinend möchten Sie die Bereiche von "s3.txt" ("getestete Bereiche"), die in einem Bereich in "s4.txt" ("enthaltende Bereiche") enthalten sind. In diesem Fall liegt Ihr Fehler vermutlich im Vergleich der Start- und Endkoordinaten. Man beachte "t_start" und "t_end" die Koordinaten des getesteten Bereichs und "c_start" und "c_end" die Koordinaten des enthaltenen Bereichs. Was Sie wollen, ist `c_start <= t_start und t_end <= c_end`.
Ich habe Ihre Frage bearbeitet, um aussagekräftigere Variablennamen zu verwenden, und ich habe auch "1 5 20" aus der erwarteten Ausgabe entfernt: Wenn ich das richtig verstanden habe, ist dies nicht das, was Sie wollen, da dies in keinem der in "s4" definierten Bereiche enthalten ist .txt`
Ich kann keine Antwort posten, da Ihre Frage "in der Warteschleife" ist, aber hier ist eine (hoffentlich) korrigierte Version Ihres Codes mit geringfügigen Verbesserungen des Codierungsstils und Verwendung von python3: http://paste.ubuntu.com/24915950 /Ich hoffe das hilft.
ohh ich war ein bisschen weg, so viele vorschläge danke euch allen. Ich werde meinen Beitrag bearbeiten, sobald ich jeden Ihrer Vorschläge durchgegangen bin
@AlexReynolds hat eine Antwort hinzugefügt
@bli Vielen Dank für die Bereinigung Code hinzugefügt Antwort
Sie sagen, "welche Koordinaten aus meiner Datei s3 auf oder zwischen meinen Referenzkoordinaten in s4 liegen". Wenn ich das richtig interpretiere, bedeutet dies, dass Sie auch teilweise Überlappungen akzeptieren, nicht nur vollständige Einschlüsse. Dann sollte die gewünschte Ausgabe alle Bereiche in s3 sein und nicht die eingeschränkte Liste, die ich fälschlicherweise korrigiert habe.
@novicebioinforesearcher Es sieht so aus, als ob `bedops` Ihr fehlendes Intervall finden konnte. Wenn Sie sich mit Strangbezeichnungen in der sechsten Spalte befassen müssen (gemäß BED-Spezifikation), können Sie eine BED-Datei nach Strang über "awk" $ 6 == "+" "in.bed> in.forward.bed" und "awk" aufteilen '$ 6 == "-"' in.bed> in.reverse.bed` und führen Sie dann Set-Operationen für jede der Strang-Split-Dateien aus. Wenn Sie am Ende eine Datei rekonstruieren müssen, verwenden Sie `bedops -u`, um eine Multiset-Vereinigung aller eingegebenen BED-Dateien durchzuführen.
Vier antworten:
Devon Ryan
2017-06-21 00:39:00 UTC
view on stackexchange narkive permalink

Sie erfinden bedtools intersect (oder bedops) neu, für die es bereits ein praktisches Python-Modul gibt:

  von pybedtools importieren BedTools3 = BedTool ('s3.bed') s4 = BedTool ('s4.bed') print (s4.intersect (s3, wa = True, wb = True, F = 1) )  

Das wb = True entspricht -wb , wobei sich Bedtools in der Befehlszeile schneiden. In ähnlicher Weise ist F = 1 dasselbe wie -F 1 .

`NotImplementedError:" intersectBed "scheint nicht installiert zu sein oder sich im Pfad zu befinden, daher ist diese Methode deaktiviert. Bitte installieren Sie eine neuere Version von BEDTools und importieren Sie sie erneut, um diese Methode zu verwenden. "Verwendet pip install pybedtools
Sie sollten lesen und verstehen können, wie Sie mit dieser Fehlermeldung umgehen.
Hallo, ich habe Bedtools installiert. Ist eine Umgebungsvariable. Ich kann sie in Bash aus jedem Verzeichnis verwenden. Ich erhalte immer noch den gleichen Fehler. Gibt es einen anderen Weg als diesen? Vielen Dank
Sie können es jederzeit über conda installieren, obwohl es für mich mit der veralteten Version der von mir installierten Bedtools (2.25.0) funktioniert.
Ich konnte es zum Laufen bringen, danke, aber das Ergebnis scheint nicht eindeutig zu sein. Ich habe es meinem ursprünglichen Beitrag hinzugefügt. 5-20 scheinen zu fehlen
Ob Sie "F = 1" oder "f = 1" möchten, hängt von Ihren genauen Anforderungen und der Reihenfolge ab, in der Sie die Dinge tun.
bli
2017-06-21 20:27:07 UTC
view on stackexchange narkive permalink

Bezüglich Ihres Python-Codes

Wenn Sie die experimentellen Bereiche möchten, die vollständig in einem der Referenzbereiche enthalten sind , müssen Sie die Koordinaten in der folgenden Reihenfolge haben:

  cst < = tst < ten < = cen  

Wenn Sie möchten, sind die experimentellen Bereiche, die einen der Referenzbereiche strong überlappen > muss entweder der Anfang oder das Ende des experimentellen Bereichs innerhalb des Referenzbereichs liegen:

  (cst < = tst < cen) oder (cst < ten < = cen)  

Ihr Code entspricht keiner der beiden Möglichkeiten:

  cst > = tst und cen < = ten  

Dies ist äquivalent zu:

  tst < = cst und cen < = zehn  

(oder tst < = cst < cen < = ten , da wir wissen, dass cst < cen , per Definition eines Bettes inter val).

Mit diesem Umschreiben können wir leichter erkennen, dass Sie tatsächlich die experimentellen Bereiche auswählen, die einen Referenzbereich enthalten.

Hier einige (python3) Code, der Ihnen die Ergebnisse in den beiden anderen Situationen liefert:

  #! / usr / bin / env python3ref_intervals = [] mit open ("s4.txt", "r") als f: für Zeile in f: (chr, start, end) = line.strip (). split ("\ t") ref_intervals.append ((chr, int (start), int (end))) exp_intervals = [ ] mit open ("s3.txt", "r") als f: für Zeile in f: (chr, start, end) = line.strip (). split ("\ t") exp_intervals.append ((chr, int (start), int (end))) enthalten = [] überlappend = [] für (r_chr, r_start, r_end) in ref_intervals: für (e_chr, e_start, e_end) in exp_intervals: wenn e_chr == r_chr: wenn r_start < = e_start < r_end oder r_start < e_end < = r_end: overlapping.append ((e_chr, e_start, e_end))
wenn r_start < = e_start < e_end < = r_end: enthält "\ t") print ("enthalten") für (chr, start, end) in enthalten: print (chr, start, end, sep = "\ t")  

Wenn ich Wenn Sie es ausführen, erhalte ich die folgenden Ergebnisse:

  $ ./overlap.py überlappend1 10 201 5 201 10 501 14 172 20 302 25 302 20 60contained1 10 201 14 172 20 302 25 30  

Es ist wahrscheinlich eine gute Übung, dies zu programmieren, aber wie die anderen Antworten zeigen, gibt es effiziente Tools, die in einer professionellen Umgebung eine bessere Lösung darstellen würden .

Das macht Sinn, ich denke, ich muss anfangen, wie ein Programmierer zu denken und zu sprechen, was mir helfen würde, die Fragen wie eine zu schreiben. Sicher, es gibt andere Tools, aber wenn ich es selbst mache, kann ich lernen und verstehen, was genau hinter den Tools steckt.
Alex Reynolds
2017-06-21 00:35:59 UTC
view on stackexchange narkive permalink

Sie können stattdessen BEDOPS verwenden:

  $ sort-bed s3.txt > s3.bed $ sort-bed s4.txt > s4.bed $ bedops --element-of 1 s3.bed s4.bed > answer.bed  

Wenn Sie es in Python ausführen müssen, können Sie subprocess.check_output () :

  Unterprozess importieren ... try: result = subprocess.check_output ("bedops --element-von 1% s% s >% s"% (set_a_fn, set_b_fn, answer_fn ), shell = True) außer subprocess.CalledProcessError als err: erhöhe SystemExit ("Bedops konnten nicht ausgeführt werden \ n") # mache Sachen mit 'result'  
Danke, ich würde es auf jeden Fall versuchen, aber können Sie mir bitte helfen, zu verstehen, was mit meiner Logik / meinem Code nicht stimmt?
Du bist besser dran, das Rad nicht neu zu erfinden, ist mein Rat. Python ist nicht das richtige Werkzeug für Set-Operationen.
Wenn Sie dies wirklich tun möchten, verwenden Sie Debug-Anweisungen (`sys.stderr.write (...)`), damit Sie sehen können, was in jeder Phase passiert.
Wenn dies eine Hausaufgabe ist und Sie Ihre eigene Lösung von Grund auf neu schreiben müssen, fügen Sie Ihrer Frage ein "Hausaufgaben" -Tag hinzu, um dies deutlich zu machen. Wir helfen Ihnen gerne bei Fragen zu Hausaufgaben, aber die Antworten werden wahrscheinlich unterschiedlich (und hoffentlich entgegenkommend) sein.
Wenn es sich nicht um eine Hausaufgabe handelt, hat Alex Recht: Verwenden Sie besser getestete Werkzeuge für die Intervallarithmetik.
@DanielStandage Ja, es sind Hausaufgaben, die Änderungen am Tag vornehmen. Wenn ich es versuche, kann ich kein Tag erstellen
@novicebioinforesearcher Ich habe das Hausaufgaben-Tag zu Ihrem Beitrag hinzugefügt.
@AlexReynolds berücksichtigt die vorgeschlagene Methode auch den Strang?
Ich bin mir nicht sicher. Ich sehe nichts in Ihrem Code, das Intervalle nach Strang trennt. Sie können dazu ʻawk ($ 6 == "+") `usw. verwenden.
@AlexReynolds Entschuldigung für die späte Antwort Ich war neugierig, dass Sie Recht haben. Mein Code behandelt keinen Strang. Bedops ist neu für mich. Daher wollte ich Sie bitten, Sie im Voraus zu installieren und mit den Ergebnissen zu aktualisieren
The Unfun Cat
2019-10-29 16:03:23 UTC
view on stackexchange narkive permalink

pyranges Antwort:

  # pip install pyranges # oder # conda install -c bioconda pyrangesimport pyranges as prs3 = pr.read_bed ("s3.bed") s4 = pr.read_bed ("s4.bed") s3.intersect (s4, how = "Containment")  

Antwort mit Setup (Bearbeiten):

  Pandas als pd aus importieren StringIOimport pyranges als prc1 = "" 1 10 201 5 202 20 302 25 301 10 502 20 601 14 17 "" c2 = "" 1 10 202 20 30 "" column = "Chromosom Start End" .split () df1 = pd.read_table (StringIO (c1), sep = "\ s +", header = Keine, Namen = Spalten) df2 = pd.read_table (StringIO (c2), sep = "\ s +", header = Keine, Namen = Spalten) gr1 = pr.PyRanges (df1) gr2 = pr.PyRanges (df2) print (gr1.intersect (gr2, how = "Containment"))  

Ergebnis:

  + -------------- + ----------- + ----- ------ + | Chromosom | Start | Ende || (Kategorie) | (int32) | (int32) || -------------- + ----------- + ----------- || 1 | 10 | 20 || 1 | 14 | 17 || 2 | 20 | 30 || 2 | 25 | 30 | + -------------- + ----------- + ----------- + Unstranded PyRanges-Objekt hat 4 Zeilen und 3 Spalten aus 2 Chromosomen. Zum Drucken wurden die PyRanges nach Chromosomen sortiert.  


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...