Zählen von Werten zwischen zwei durch zwei Spalten definierten Werten

Zählen von Werten zwischen zwei durch zwei Spalten definierten Werten

Ich habe Daten in drei Spalten wie folgt gespeichert:

3651 3631 3913
3667 3996 4276
3674 4486 4605
3707 4706 5095
3720 5174 5326
3750 5439 5899
3755 5928 6263
3767 6437 7069
3779 7157 7232
3882 7384 7450
3886 7564 7649
3900 7762 7835
4006 7942 7987
4015 8236 8325
4026 8417 8464
4065 8571 8737
4156 6790 7069
4493 7157 7450
4541 7564 7649
4551 7762 7835
4597 7942 7987
4756 8236 8325
4776 8417 8464

wobei die 1. Spalte ein bestimmter Wert ist, die 2. Spalte der Anfang und die 3. Spalte das Ende. Es gibt 825849 Zeilen in der 1. Spalte und 58386 in der 2. und 3. Spalte. Ich muss Werte ab der 1. Spalte zählen, wenn sie zwischen Anfang und Ende liegen.

Ich weiß, dass in meiner Datei die ersten 12 spezifischen Werte aus Spalte Nr. 1 zwischen dem ersten Anfang und Ende liegen, die nächsten 5 zwischen dem zweiten Anfang und Ende und so weiter. Ich muss die gesamte Datei überprüfen. Ich habe es damit versucht und es funktioniert, ist aber sehr langsam:

coords='final_exons.txt'

snp=( $( cat $coords | awk '{print $1}') )
exon_start=( $( cat $coords | awk '{print $2}') )
exon_end=( $( cat $coords | awk '{print $3}') )

i=0
counter=0
for value in ${exon_end[@]}; do
    new_val=$counter
    counter=0
    let "i++"
    for snps in ${snp[@]}; do

        if [[ $value > $snps ]]; then
            #statements
            let "counter++"
            #$counter=$(echo "scale=2; $counter-$new_val" | bc)
        else
            #$new_val=$(echo "scale=2; $counter-$")
            break
        fi
    done
    #echo "NOWENOWE $new_val "
    #echo "COUNTER $value : $counter "
    final=$(echo "scale=2; sqrt(($counter-$new_val)^2)" | bc)
    echo "Exon $i : $final SNPs"
done

Vielen Dank im Voraus für alle Hinweise und Tipps

Link für vollständige Daten

Antwort1

  1. Tragen Sie jeden Wert in eine Zeile ein, aber markieren Sie „Start“ und „Ende“, indem Sie sie anhängen Soder E. Sortieren Sie die Werte nun numerisch. Sie erhalten dann etwa Folgendes:
3631S
3651
3667
...
3900
3913E
3996S
4006
...
  1. Zählen Sie die Vorkommen zwischen einem Sund einem Ebeendeten Wert.

Schreiben Sie das Drehbuch und seien Sie glücklich!

awk '
    {print $1} 
    $3!="" {print $2"S"; print $3"E"} 
' final_exons.txt | sort -n | awk '
    !/E|S/ {count++; next}
    /S/ {count=0; next}
    /E/ {print line++": "count}'

Das erste awkund sortführen Sie Schritt 1 aus. Es gibt einen $3!=""Test (es könnte auch sein $2!=""), weil in der 1. Spalte mehr Zeilen stehen als in der 2. oder 3.

Der zweite awkentspricht Schritt 2. Er setzt den Zähler zurück, wenn er Zeilen mit liest S, erhöht ihn, wenn die Zeile keine Markierung hat, und druckt ihn (zusammen mit der Zeilennummer), wenn er Zeilen mit liest E.

Die Ausgabe beim Ausführen der von Ihnen bereitgestellten Beispieldatei lautet 0: 12; 1: 5; 2: 4; 3: 2; ...; 22: 0:

Antwort2

Ich könnte ein awk gebrauchen:

awk '{if( ($1 > $2) && ($1 < $3) ){print NR" "$1" "$2" "$3}}' final_exons.txt

Wenn jedoch col1 und (col2 und col3) separat behandelt werden, ist es besser, sie in separate Dateien aufzuteilen. Oder Sie legen die Daten in die Datenbank und führen dann den Intervalltest darin durch. Der effizienteste Weg könnte jedoch sein, die Daten in das reguläre Array zu laden und die Testschleifen in einer anderen Skriptsprache (PHP, Python, Perl ...) auszuführen.

verwandte Informationen