Подсчет значений между двумя значениями, определенными двумя столбцами

Подсчет значений между двумя значениями, определенными двумя столбцами

У меня есть данные, хранящиеся в трех столбцах, например:

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

где 1-й столбец — это определенное значение, 2-й столбец — начало, а 3-й столбец — конец. В 1-м столбце 825849 строк, а во 2-м и 3-м — по 58386. Мне нужно посчитать значения из 1-го, если они находятся между началом и концом.

Я знаю, что в моем файле первые 12 конкретных значений из столбца № 1 находятся между первым началом и концом, следующие 5 — между вторым началом и концом и т. д. Мне нужно проверить весь файл. Я пробовал с этим, и это работает, но очень медленно:

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

Заранее спасибо за любые подсказки и советы.

ссылка для полных данных

решение1

  1. Поместите каждое значение в строку, но отметьте "начало" и "конец", добавив их Sили E. Теперь отсортируйте значения по номерам. Вы получите что-то вроде
3631S
3651
3667
...
3900
3913E
3996S
4006
...
  1. Подсчитайте количество вхождений между a Sи Eконечным значением.

Напишите сценарий и будьте счастливы!

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}'

Первый awkи sortвыполнить шаг 1. Есть $3!=""тест (он также может быть $2!=""), потому что в 1-м столбце больше строк, чем во 2-м или 3-м.

Второй awkсоответствует шагу 2. Он сбрасывает счетчик, если считывает строки с S, увеличивает его, если строка не имеет маркера, и печатает его (вместе с номером строки), если считывает строку с E.

Вывод при запуске предоставленного вами файла-образца: 0: 12; 1: 5; 2: 4; 3: 2; ...; 22: 0.

решение2

Я мог бы использовать awk:

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

Но если col1 и ( col2 и col3 ) обрабатываются отдельно, вам лучше вынести их в отдельные файлы. Или поместить данные в базу данных и затем выполнить интервальный тест внутри нее. Но наиболее эффективным способом может быть загрузка данных в обычный массив и реализация тестовых циклов на каком-то другом языке сценариев ( php, python, perl ...)

Связанный контент