| Autor |
Mensaje |
adtito

Forista Nuevo
Registrado: Sab Sep 26, 2009 11:00 pm Mensajes: 4
|
 Publicado: Dom Sep 27, 2009 1:29 pm |
|
|
Hola,
Que tal, empiezo con esto de la línea de comendo en unix y estoy tratando de realizar un pequeño scrip para generar lineas de texto aleatorias, pero no lo he logrado. Se trata de generar una lista de archivos, dentro de los cuales cada uno de dichos archivos contenga una secuencia aleatoria de ADN. Cada secuencia debe contener 50 nucleotidos distribuidos aleatoriamente. Los nucleotidos pueden ser solo a,c,g y t y la cadena de texto debe contener dichas letras en un conjunto de 50
Sería algo asi:
Seq1 aaagggttttccc........hasta 50
Seq2 tttccaaaccca.........hasta 50
Seq3 ggttaaccc..............
Mi problema es el generar la cadena de texto aleatoria...., ojala me puedan ayudar
* Mensaje movido por el administrador del foro Debates al foro Programación por pertenecer mejor a esta temática. Por favor, revisa la descripción de cada foro.
|
|
|
|
 |
Profetta

Forista Medio
Registrado: Vie Ene 26, 2007 12:00 am Mensajes: 113 Ubicación: México
|
 Publicado: Dom Sep 27, 2009 9:34 pm |
|
|
Bueno, no mencionas que lenguaje de programación utilizas, pero puedo sugerirte que guardes en un array las letras que necesitas y luego generes un par de bucles con un random para guardarlas, algo como:
c[1]="a"
c[2]="c"
c[3]="g"
c[4]="t"
para x=1 hasta 20 (para 20 secuencias)
valor[x]=""
para y=1 hasta 50
valor[x]=valor[x]+c[numero_aleatorio(4)]
siguiente y
siguiente x
Así es como lo haría. Espero te sea de utilidad
_________________ Usuario Linux #463425
Corriendo LinuxMint 7.0... Cool!
|
|
|
|
 |
adtito

Forista Nuevo
Registrado: Sab Sep 26, 2009 11:00 pm Mensajes: 4
|
 Publicado: Lun Sep 28, 2009 10:15 am |
|
|
muchas gracias, estoy haciendolo en el bash Shell, pero apenas comienzo y había hecho esto:
n[1]=a
n[2]=c
n[3]=g
n[4]=t
for i in {1..10}; do
echo ${n[*]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[@]} ${n[1]} ${n[4]}
done
sin embargo, todavía no se manejar el $RANDOM, ojalá me puedas dar una pista sobre esto
|
|
|
|
 |
Profetta

Forista Medio
Registrado: Vie Ene 26, 2007 12:00 am Mensajes: 113 Ubicación: México
|
 Publicado: Lun Sep 28, 2009 2:53 pm |
|
_________________ Usuario Linux #463425
Corriendo LinuxMint 7.0... Cool!
|
|
|
|
 |
akodo

Moderador
Registrado: Mié Nov 28, 2007 12:00 am Mensajes: 1361 Ubicación: En la X del explorer (pulse para llamar)
|
 Publicado: Lun Sep 28, 2009 3:02 pm |
|
http://tldp.org/LDP/abs/html/randomvar.html
El enlace contiene código que te puede resultar útil para manejar los números aleatorios.
En cuanto al código, no es para nada recomendable que pongas un "echo" tan largo, y más si tienes que generar un número aleatorio en cada "${n[]}" que has puesto.
Voy a suponer que tienes una función que te devuelve un número aleatorio entre 1 y 4. No es muy complicado hacerla basándote en el enlace que te he puesto, aunque tampoco necesitas la función.
Código: for i in {1..10} ; do #suponiendo que se pueda hacer así for j in {1..50} ; do indice=<numero aleatorio> echo "${n[$indice]} " done done
${n[*]} te devuelve todas las componentes del array, creo que separadas por espacios y ${n[@]} no sé lo que hace.
PD: al final acaba en el mismo sitio... 
_________________ Descargue el gestor de mp3 "Music Manager" -> (mmlf)
Última versión del gestor "Music Manager" -> (jmmm)
|
|
|
|
 |
adtito

Forista Nuevo
Registrado: Sab Sep 26, 2009 11:00 pm Mensajes: 4
|
 Publicado: Mar Sep 29, 2009 3:38 pm |
|
|
Hola de nuevo,
Gracias a su ayuda logré generar las letras aleatorias, solo me falta redireccionarlas a un archivo, lo trate de hacer con ">" pero me dice que hay un error de sintaxis. Les dejo el código y espero me puedan ayudar otra vez
seq=i
nuc="a
c
g
t"
for i in {1..2000}; do
for i in {1..50}; do
nucs=($nuc)
num_nuc=${#nucs[@]}
echo${nucs[$((RANDOM%num_nuc))]}
done
echo ( ${nucs[$((RANDOM%num_nuc))]} )>seq$i
done
|
|
|
|
 |
Pratt

Forista Medio
Registrado: Mié May 04, 2005 11:00 pm Mensajes: 353 Ubicación: Bogotá
|
 Publicado: Mar Sep 29, 2009 8:20 pm |
|
Saludos!
El error radica en la linea:
Código: RANDOM%num_nuc
Debes especificar que son variables, con el signo de dolar ($) Código: $RANDOM%$num_nuc
Y luego quitarle los parentesis al segundo echo. La unica "falla" que tendria tu script, es que no estas concatenando la salida para generar una cadena de 50 nucleotidos. Cada nucleotidos va a salir en una linea distinta. De todas maneras, lo podrias intentar con el siguiente script. La unica diferencia es que estoy usando un array para guardar los nucleotidos y estoy usando el comando seq para hacer las secuencias: Código: #!/bin/bash elementos=( a c g t ) for i in $(seq 1 10); do for j in $(seq 1 50); do combinacion=$combinacion${elementos[(($RANDOM%${#elementos[*]}))]} done echo $combinacion #echo $combinacion > secuencia-$i unset combinacion done
Chaolander
_________________ Mi Foro: http://www.hablarmierda.net
Mi Blog: http://www.michael-pratt.com/blog
Mis Distros: Slackware (Current)| Archlinux
|
|
|
|
 |
adtito

Forista Nuevo
Registrado: Sab Sep 26, 2009 11:00 pm Mensajes: 4
|
 Publicado: Mié Sep 30, 2009 10:29 am |
|
|
Muchas gracias a todos!!!
|
|
|
|
 |
fitorec

Forista Nuevo
Registrado: Mié Ene 05, 2011 1:43 am Mensajes: 4
|
 Publicado: Mié Ene 05, 2011 4:33 am |
|
Lo que creo que se esta abordando como una solución basada en arreglos o listas, la veo mas como un tratamiento de cadenas, dejo mi solución: Código: cad='' while [ `expr "$cad" : '.*'` -lt 50 ]; do cad_aux=`echo $RANDOM | md5sum | sed "s/8/t/g;s/9/g/g" | sed -r "s/[^acgt]//g"` cad=$cad$cad_aux done echo $cad | cut -c 1-50
En algunas documentaciones recomiendan hacer doble tubería al md5(ignoro del todo el concepto) lo cual denominan como **Doubly scramble**, lo que seria algo como: Código: echo $RANDOM | md5sum | md5sum | sed "s/8/t/g;s/9/g/g" | sed -r "s/[^acgt]//g"
Editado -- Mié Ene 05, 2011 4:33 am --Me siguen quedando mis dudas al menos que el $RANDOM implemente algún algoritmo de numeros aleatorios como el "Mersenne Twister" me convencería, por lo pronto dejo otra solución con el mismo enfoque(Manejo de cadenas). Código: cadenaAleatoria=`</dev/urandom tr -dc acgt | head -c 50` echo $cadenaAleatoria
|
|
|
|
 |
t4rr1t0

Ganador CSEL 2011
Registrado: Dom Dic 12, 2010 10:07 am Mensajes: 313
|
 Publicado: Mié Ene 05, 2011 8:24 am |
|
Hola, no se mucho de Bash, pero en Perl yo lo haría así: Código: #!/usr/bin/perl -w
my @letras=("a","c","g","t"); #arreglo de letras my $sec_mezclada; #declaración variable
for ($secuencias=0;$secuencias<=19;$secuencias++){ #cantidad de secuencias for ($random=0;$random<=49;$random++){ #largo secuencia $sec_mezclada.= $letras[int(rand($#letras+1))]; } print $sec_mezclada,"\n"; $sec_mezclada=undef;#reiniciar la variable }
Salu2
|
|
|
|
 |
fitorec

Forista Nuevo
Registrado: Mié Ene 05, 2011 1:43 am Mensajes: 4
|
 Publicado: Mié Ene 05, 2011 11:17 pm |
|
Para ser honesto nunca e programado en perl, me late su manejo de cadenas, conozco un poco del su lenguaje mas cercano (y mas fuerte competidor python), y en python ese mismo código una forma de representarlo en python seria: Código: #!/usr/bin/env python import random
for i in range(20): sec_mezclada = [ random.choice('acgt') for i in range(50) ] print ''.join(sec_mezclada)
Sin embargo creo que se podría solucionar de una mejor manera, pero me gustaría mas seguir discutiendo desde el contexto de Bash. Saludos!.
|
|
|
|
 |
akodo

Moderador
Registrado: Mié Nov 28, 2007 12:00 am Mensajes: 1361 Ubicación: En la X del explorer (pulse para llamar)
|
 Publicado: Jue Ene 06, 2011 9:36 am |
|
fitorec escribió: Sin embargo creo que se podría solucionar de una mejor manera, pero me gustaría mas seguir discutiendo desde el contexto de Bash.
Lo dudo. Se podrá optimizar algo más, pero la idea va a seguir siendo la misma. La idea es hacer una selección aleatoria de los elementos de un array que contenga los caracteres (en este caso) que se vayan a poner. Ya se han expuesto algunos ejemplos en post anteriores. La otra posible aproximación es generar una secuencia númerica, y sustituirla de una sola pasada por el elemento correspondiente. Por ejemplo, si tenemos los valores "agtc", asignamos una correspondencia con unos valores númericos "1234" (o "0123", si puede suponer algún problema). Luego generamos una cadena de números que, debido a los pocos elementos que existen, se pueden concatenar sin problema. Así tenemos la secuencia "1243124312432" por ejemplo. Ahora sólo habría que sustituir los números por los valores correspondientes. El problema es que para que funcione de una manera eficiente tiene que haber un máximo de 9 o 10 elementos (uno por cada número de un dígito) de forma que se puedan concatenar los números de una forma no ambigua, y además la sustitución de los elementos se debe hacer en una sola pasada (hacerlo en varias es claramente ineficiente).
_________________ Descargue el gestor de mp3 "Music Manager" -> (mmlf)
Última versión del gestor "Music Manager" -> (jmmm)
|
|
|
|
 |
fitorec

Forista Nuevo
Registrado: Mié Ene 05, 2011 1:43 am Mensajes: 4
|
 Publicado: Jue Ene 06, 2011 1:03 pm |
|
lo que akodo dice es básicamente un: Código: echo `</dev/urandom tr -dc 1234 | head -c 50 | sed 's/1/a/g;s/2/c/g;s/3/g/g;s/4/t/g'` Realmente yo me refería mas a la forma de como generar la parte seudo aleatoria cuando decia q se podría mejorar. Esto me pone en una contradicción ya que creo que en este caso poco importa el lenguaje de programación. En fin creo que de alguna u otra forma ya se habia resuelto en este sentido creo que poco aporta mi participación.
|
|
|
|
 |
t4rr1t0

Ganador CSEL 2011
Registrado: Dom Dic 12, 2010 10:07 am Mensajes: 313
|
 Publicado: Jue Ene 06, 2011 2:13 pm |
|
|
Creo que lo que se podría agregar seria una función para evitar que una secuencia se repita, lo cual si bien es una posibilidad remota, no deja de ser posible. Pero la verdad no se si el problema original lo requiere (adtito no lo especifica).
|
|
|
|
 |
fitorec

Forista Nuevo
Registrado: Mié Ene 05, 2011 1:43 am Mensajes: 4
|
 Publicado: Jue Ene 20, 2011 10:59 pm |
|
t4rr1t0 escribió: Creo que lo que se podría agregar seria una función para evitar que una secuencia se repita, lo cual si bien es una posibilidad remota, no deja de ser posible. Pero la verdad no se si el problema original lo requiere (adtito no lo especifica). Eso es sencillo, si por ejemplo vamos generando las cadenas aleatorias a la vez que las apilamos en una archivo de texto, bastaría con quitar elementos repetidos del archivo, dejo las instrucciones necesarias: Código: #generamos una cadena aleatoria y la mandamos al final. echo `</dev/urandom tr -dc acgt | head -c 50`>> cadenas_aleatorias.txt #ordenamos el archivo, quitamos repetidos y lo volvemos a guardar en el mismo archivo. sort -u cadenas_aleatorias.txt -o cadenas_aleatorias.txt #comando sort ordena y con las opciones. #-u: elimina elementos repetidos. #-o: la salida la manda a un archivo(en este caso el mismo archivo cadenas_aleatorias.txt)
Respecto a esta solución a mi parecer estaría mal, a mi juicio al implementar esto estaríamos perdiendo un cierto grado de entropía en nuestras muestras,ya que la aleatoriedad podría contemplar elementos repetidos.
|
|
|
|
 |
|
|
|