Tengo datos almacenados en tres columnas como esta:
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
donde la primera columna es un valor específico, la segunda columna es el inicio y la tercera columna es el final. Hay 825849 líneas en la primera columna y 58386 en la segunda y tercera. Necesito contar los valores desde el primero si están entre el inicio y el final.
Sé que en mi archivo los primeros 12 valores específicos de la columna número 1 están entre el primer inicio y el final, los 5 siguientes están entre el segundo inicio y el final, y así sucesivamente. Necesito revisar el archivo completo. Lo he probado con esto y funciona pero muy lento:
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
Gracias de antemano por cualquier sugerencia y consejo.
Respuesta1
- Coloque cada valor en una línea, pero marque "inicio" y "fin" agregándolos
S
oE
. Ahora ordena los valores numéricamente. Obtendrías algo como
3631S
3651
3667
...
3900
3913E
3996S
4006
...
- Cuente las ocurrencias entre
S
ay unE
valor terminado.
¡Escribe el guión y sé feliz!
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}'
La primera awk
y sort
realiza el paso 1. Hay una $3!=""
prueba (también podría ser $2!=""
) porque hay más líneas en la 1ª columna que en la 2ª o 3ª.
El segundo awk
corresponde al paso 2. Reinicia el contador si lee líneas con S
, lo incrementa si la línea no tiene marcador y lo imprime (junto con el número de línea) si lee la línea con E
.
El resultado cuando se ejecuta en el archivo de muestra que proporcionó es 0: 12; 1: 5; 2: 4; 3: 2; ...; 22: 0
.
Respuesta2
Me vendría bien un awk:
awk '{if( ($1 > $2) && ($1 < $3) ){print NR" "$1" "$2" "$3}}' final_exons.txt
Pero si col1 y (col2 y col3) se tratan por separado, es mejor separarlos en archivos separados. O coloque los datos en la base de datos y luego realice la prueba de intervalo dentro de ella. Pero la forma más eficiente podría ser cargar los datos en la matriz normal y realizar los bucles de prueba en algún otro lenguaje de programación (php, python, perl...)