Domanda:
Errore di Python di sovrapposizione dell'intervallo con le regioni genomiche
novicebioinforesearcher
2017-06-21 00:26:57 UTC
view on stackexchange narkive permalink

Ho due file

  s3.txt: 1 10201 5 202 20 302 25 301 10502 20601 14 17s4.txt: 1 10 202 20 30  

Sto cercando di abbinare col0 di entrambi i file e ottenere righe che rientrano nell'intervallo (compreso di se stesse) 10-20 e 20-30 come si vede nel file s4. file s4 ha coordinate che possono essere utilizzate come intervallo di riferimento (inizio e fine crom) e s3 ha un elenco di coordinate da una condizione sperimentale, ciò che sto cercando di ottenere è a quali coordinate dal mio file s3 cadono su o tra le mie coordinate di riferimento in s4.

codice fino ad ora:

  Contain_ranges = [] con open ('s4.txt', 'r') come f: for line in f: fields = line. strip (). split ('\ t') contenente_ranges.append (campi) intervallo_estato = [] con open ('s3.txt', 'r') come f: per riga in f: fields = line.strip (). split ('\ t') intervallo_estato.append (campi) per intervallo_c in intervallo_contenente: per intervallo_t in intervallo_stato: tst = int (intervallo_t [1]) ten = int (intervallo_t [2]) cst = int (intervallo_c [1]) cen = int (c_range [2]) if c_range [0] == t_range [0]: included = cst > = tst and cen < = ten if included == True: print t_range  

Output con riga mancante (1 14 17):

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

Output desiderato:

  1 10 202 20 302 25 301 14 17  

Non so se la mia logica è sbagliata e perché manca 14-17 come ho t è compreso tra 10-20

  [EDIT] utilizzando pybedtools>>> print (s4.intersect (s3, wb = True)) 1 10 20 1 10201 10 20 1 5201 10 20 1 10501 14 17 1 14172 20 30 2 20302 25 30 2 25302 20 30 2 20 60>>> print (s4.intersect (s3, wa = True, wb = True, F = 1)) 1 10 20 1 10201 10 20 1 14172 20 30 2 20 30
2 20 30 2 25 30usando bedops bin $ less answer. Bed 1 5201 10201 10501 14172 20302 20602 25 30usando codice @bli (su python2.7) ('1', 10, 20) ('1' , 14, 17) ('2', 20, 30) ('2', 25, 30) perché non riesco a vedere l'intervallo 1 5 20  
Che risultato ottieni con `bedops --element-of`?
Porta le tue domande sulla logica / codifica a Stack Overflow. La relazione tra la tua domanda e il tema della bioinformatica è puramente casuale.
@RobertC Se OP aggiunge un tag "bed", questa domanda apparirà immediatamente come una domanda di bioinformatica. Inoltre, guarda le risposte. È molto più probabile che OP ottenga risposte così precise qui. Questa domanda potrebbe essere migliorata di sicuro, ma non è fuori tema.
Usa solo le sponde del letto, come indicato. L'uso di wrapper per strumenti da riga di comando è raramente un sostituto per l'apprendimento degli strumenti.
Puoi aggiungere più storia / contesto intorno a questa domanda? Ha l'aspetto di una pura questione di programmazione (presumibilmente perché è stato contrassegnato come fuori tema). Sarebbe bello se potessi spiegare cosa significano i diversi numeri e perché vuoi farlo.
Dovresti usare nomi più significativi per le tue variabili. Renderebbe il codice più facile da leggere, per gli altri ma anche per te.
Sembra che tu voglia gli intervalli da `s3.txt` (" intervalli testati ") che sono inclusi in un intervallo in` s4.txt` ("intervalli contenenti"). In questo caso, penso che il tuo errore sia nel confronto delle coordinate di inizio e fine. Notiamo `t_start` e` t_end` le coordinate dell'intervallo testato e `c_start` e` c_end` le coordinate dell'intervallo contenente. Quello che vuoi è `c_start <= t_start e t_end <= c_end`.
Ho modificato la tua domanda per utilizzare nomi di variabili più significativi e ho anche rimosso "1 5 20" dall'output previsto: Se ho capito correttamente, questo non è quello che vuoi perché non è incluso in nessuno degli intervalli definiti in "s4 .txt`
Non posso pubblicare una risposta poiché la tua domanda è "in attesa", ma ecco una versione corretta (si spera) del tuo codice, con piccoli miglioramenti nello stile di codifica e utilizzando python3: http://paste.ubuntu.com/24915950 /Spero che questo possa essere d'aiuto.
ohh sono stato via per un po ', tanti suggerimenti grazie a tutti. modificherà il mio post una volta che avrò esaminato ciascuno dei tuoi suggerimenti
@AlexReynolds ha aggiunto la risposta
@bli grazie per aver ripulito il codice aggiunto risposta
Dici "quali coordinate dal mio file s3 ricadono su o tra le mie coordinate di riferimento in s4". Se lo interpreto correttamente, significa che accetti anche sovrapposizioni parziali, non solo inclusioni complete. Quindi l'output desiderato dovrebbe essere tutti gli intervalli in s3 e non l'elenco limitato che ho erroneamente corretto.
@novicebioinforesearcher Sembra che "bedops" sia riuscito a trovare l'intervallo mancante. Se hai bisogno di gestire le etichette dei filamenti nella sesta colonna (secondo le specifiche BED), puoi dividere un file BED per filamento tramite `awk '$ 6 ==" + "' in.bed> in.forward.bed` e` awk '$ 6 == "-"' in.bed> in.reverse.bed`, quindi eseguire operazioni di impostazione su ciascuno dei file di suddivisione in trefoli. Se hai bisogno di ricostruire un file alla fine, usa `bedops -u` per fare un'unione multiset di tutti i file BED di input.
Quattro risposte:
Devon Ryan
2017-06-21 00:39:00 UTC
view on stackexchange narkive permalink

Stai reinventando bedtools intersect (o bedops), per il quale esiste già un comodo modulo python:

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

wb = True è equivalente a -wb con bedtools intersect sulla riga di comando. Allo stesso modo, F = 1 è uguale a -F 1 .

`NotImplementedError:" intersectBed "non sembra essere installato o sul percorso, quindi questo metodo è disabilitato. Installa una versione più recente di BEDTools e reimportala per utilizzare questo metodo. Utilizza pip install pybedtools
Dovresti essere in grado di leggere e capire come gestire quel messaggio di errore.
Ciao, ho installato bedtools fatto come variabile d'ambiente, posso usarlo in bash da qualsiasi directory ricevo ancora lo stesso errore, c'è un modo diverso da questo? grazie
Puoi sempre installarlo tramite conda, anche se per me funziona con la versione obsoleta di bedtools che ho installato (2.25.0).
sono riuscito a farlo funzionare grazie, ma il risultato sembra essere ambiguo l'ho aggiunto al mio post originale, sembra che manchi 5-20
Se vuoi "F = 1" o "f = 1" dipenderà dalle tue esatte esigenze e dall'ordine in cui fai le cose.
bli
2017-06-21 20:27:07 UTC
view on stackexchange narkive permalink

Riguardo al tuo codice Python

Se vuoi gli intervalli sperimentali che sono interamente contenuti in uno degli intervalli di riferimento , devi avere le coordinate nel seguente ordine:

  cst < = tst < ten < = cen  

Se quello che vuoi sono gli intervalli sperimentali che si sovrappongono a uno degli intervalli di riferimento , è necessario che l'inizio o la fine dell'intervallo sperimentale rientrino nell'intervallo di riferimento:

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

Il tuo codice non equivale a nessuna delle due possibilità:

  cst > = tst e cen < = ten  

Questo è equivalente a:

  tst < = cst e cen < = dieci  

(o tst < = cst < cen < = ten , poiché sappiamo che cst < cen , per definizione di un letto inter val).

Con questa riscrittura, possiamo vedere più facilmente che stai effettivamente selezionando gli intervalli sperimentali che contengono un intervallo di riferimento .

Ecco alcuni (python3) codice che fornisce i risultati nelle altre due situazioni:

  #! / usr / bin / env python3ref_intervals = [] with open ("s4.txt", "r") come f: per la riga in f: (chr, start, end) = line.strip (). split ("\ t") ref_intervals.append ((chr, int (start), int (end))) exp_intervals = [ ] con open ("s3.txt", "r") come f: for line in f: (chr, start, end) = line.strip (). split ("\ t") exp_intervals.append ((chr, int (inizio), int (fine))) contenuto = [] sovrapposizione = [] for (r_chr, r_start, r_end) in ref_intervals: for (e_chr, e_start, e_end) in exp_intervals: if e_chr == r_chr: if r_start < = e_start < r_end o r_start < e_end < = r_end: overlapping.append ((e_chr, e_start, e_end))
if r_start < = e_start < e_end < = r_end: contained.append ((e_chr, e_start, e_end)) print ("overlapping") for (chr, start, end) in overlapping: print (chr, start, end, sep = "\ t") print ("contenuto") per (chr, start, end) in contenuto: print (chr, start, end, sep = "\ t")  

Se I eseguendolo, ottengo i seguenti risultati:

  $ ./overlap.py overlapping1 10201 5201 10501 14172 20302 25302 20 60contained1 10201 14172 20302 25 30  

È probabilmente un buon esercizio programmarlo, ma come sottolineano le altre risposte, esistono strumenti efficienti che sarebbero una soluzione migliore in un ambiente professionale .

questo ha senso, immagino di dover iniziare a pensare e parlare come un programmatore che mi aiuterebbe a scrivere le domande come una sola. Sicuramente ci sono altri strumenti, ma farlo da solo mi aiuta a imparare e capire cosa c'è esattamente dietro gli strumenti.
Alex Reynolds
2017-06-21 00:35:59 UTC
view on stackexchange narkive permalink

Potresti usare BEDOPS, invece:

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

Se è necessario eseguirlo da Python, è possibile utilizzare subprocess.check_output () :

  import subprocess ... try: result = subprocess.check_output ("bedops --element-of 1% s% s >% s"% (set_a_fn, set_b_fn, answer_fn ), shell = True) eccetto subprocess.CalledProcessError come err: raise SystemExit ("Could not run bedops \ n") # fa cose con 'result'  
grazie lo proverei sicuramente, ma puoi aiutarmi a capire cosa c'è che non va nella mia logica / codice
Faresti meglio a non reinventare la ruota, è il mio consiglio. Python non è lo strumento giusto per le operazioni sugli insiemi.
Se vuoi davvero farlo, usa le istruzioni di debug (`sys.stderr.write (...)`) in modo da poter vedere cosa sta succedendo in ogni fase.
Se si tratta di un compito a casa e ti viene richiesto di scrivere la tua soluzione da zero, aggiungi un tag "compiti a casa" alla tua domanda per renderlo esplicito. Siamo felici di aiutare con le domande dei compiti, ma le risposte saranno probabilmente diverse (e si spera accomodanti).
Se non è un compito a casa, Alex ha ragione: meglio usare strumenti ben collaudati per l'aritmetica degli intervalli.
@DanielStandage sì, sono compiti a casa apporteranno modifiche al tag, provato a farlo non mi avrebbe permesso di creare un tag
@novicebioinforesearcher Ho aggiunto il tag homework al tuo post.
@AlexReynolds il metodo suggerito tiene conto anche del filamento?
Non ne sono sicuro. Non vedo nulla nel tuo codice che separa gli intervalli per filo. Puoi usare `awk ($ 6 ==" + ")` ecc. Per farlo.
@AlexReynolds scusa per la risposta in ritardo ero curioso che tu abbia ragione il mio codice non gestisce strand, bedops è nuovo per me, quindi volevo chiederti in anticipo che ti installerò e ti aggiornerò con i risultati
The Unfun Cat
2019-10-29 16:03:23 UTC
view on stackexchange narkive permalink

pyranges risposta:

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

Rispondi con setup (Modifica):

  importa panda come pd da io import StringIOimport pyranges come prc1 = "" "1 10 201 5 202 20 302 25 301 10 502 20 601 14 17" "" c2 = "" "1 10 202 20 30" "" colonne = "Chromosome Start End" .split () df1 = pd.read_table (StringIO (c1), sep = "\ s +", header = Nessuno, nomi = colonne) df2 = pd.read_table (StringIO (c2), sep = "\ s +", intestazione = Nessuno, nomi = colonne) gr1 = pr.PyRanges (df1) gr2 = pr.PyRanges (df2) print (gr1.intersect (gr2, how = "contenimento"))  

Risultato:

  + -------------- + ----------- + ----- ------ + | Cromosoma | Inizio | Fine || (categoria) | (int32) | (int32) || -------------- + ----------- + ----------- || 1 | 10 | 20 || 1 | 14 | 17 || 2 | 20 | 30 || 2 | 25 | 30 | + -------------- + ----------- + ----------- + L'oggetto PyRanges non incagliato ha 4 righe e 3 colonne da 2 cromosomi. Per la stampa, i PyRanges sono stati ordinati su Chromosome.  


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...