¿Cómo buscar valles en un gráfico?

10

Estoy examinando algunos datos de cobertura genómica que son básicamente una larga lista (unos pocos millones de valores) de enteros, cada uno de los cuales dice cuán bien (o "profunda") está cubierta esta posición en el genoma.

Me gustaría buscar "valles" en estos datos, es decir, regiones que son significativamente "más bajas" que su entorno.

Tenga en cuenta que el tamaño de los valles que estoy buscando puede variar de 50 bases a unos pocos miles.

¿Qué tipo de paradigmas recomendarías usar para encontrar esos valles?

ACTUALIZAR

Algunos ejemplos gráficos para los datos: texto alternativo texto alternativo

ACTUALIZACIÓN 2

Definir qué es un valle es, por supuesto, una de las preguntas con las que estoy luchando. Estos son obvios para mí: texto alternativo texto alternativo

pero hay algunas situaciones más complejas. En general, hay 3 criterios que considero: 1. La cobertura (¿promedio? ¿Máxima?) En la ventana con respecto al promedio global. 2. La (...) cobertura en la ventana con respecto a su entorno inmediato. 3. ¿Qué tan grande es la ventana: si veo una cobertura muy baja para un período corto es interesante, si veo una cobertura muy baja durante un largo periodo también es interesante, si veo una cobertura ligeramente bajo para un corto espacio es no realmente interesante , pero si veo una cobertura levemente baja durante un período largo, es ... Entonces, es una combinación de la longitud del sapn y su cobertura. Cuanto más largo es, más alto dejo la cobertura y aún lo considero un valle.

Gracias,

Dave

David B
fuente
¿Podría proporcionar una pequeña muestra de datos?
Shane
@Shane ver actualización
David B
@David Gracias. Como ambas respuestas implican, el análisis de series temporales se puede aplicar aquí ya que ha ordenado observaciones.
Shane
Esto es algo difícil de responder sin saber exactamente lo que está buscando. ¿Podrías encerrar en un círculo los puntos en las parcelas que quieres capturar? ¿Qué consideras un "valle"? ¿Qué tan bajo tiene que ir y qué esperas para volver? Es difícil formular una solución sin conocer la pregunta, es decir, los umbrales y demás.
Falmarri
@ Shane ♦ Gracias. Como tampoco tengo experiencia con el análisis de series de tiempo, ¿podría dejar algunos consejos sobre dónde debería comenzar?
David B

Respuestas:

5

Podría utilizar algún tipo de enfoque de Monte Carlo, utilizando, por ejemplo, el promedio móvil de sus datos.

Tome un promedio móvil de los datos, usando una ventana de un tamaño razonable (supongo que depende de usted decidir qué tan ancho).

Los datos en sus datos (por supuesto) se caracterizarán por un promedio más bajo, por lo que ahora necesita encontrar algún "umbral" para definir "bajo".

Para hacerlo, intercambia aleatoriamente los valores de sus datos (por ejemplo, usando sample()) y recalcula el promedio móvil de sus datos intercambiados.

Repita este último pasaje una cantidad de veces razonablemente alta (> 5000) y almacene todos los promedios de estos ensayos. Así que esencialmente tendrá una matriz con 5000 líneas, una por prueba, cada una con el promedio móvil de esa prueba.

En este punto, para cada columna, elige el cuantil del 5% (o 1% o lo que quiera), ese es el valor bajo el cual se encuentra solo el 5% de las medias de los datos aleatorios.

Ahora tiene un "límite de confianza" (no estoy seguro si ese es el término estadístico correcto) para comparar sus datos originales. Si encuentra que una parte de sus datos es inferior a este límite, puede llamar a eso a través.

Por supuesto, tenga en cuenta que ni este ni ningún otro método matemático podría darle alguna indicación de importancia biológica, aunque estoy seguro de que lo sabe.

EDITAR - un ejemplo

require(ares) # for the ma (moving average) function

# Some data with peaks and throughs 
values <- cos(0.12 * 1:100) + 0.3 * rnorm(100) 
plot(values, t="l")

# Calculate the moving average with a window of 10 points 
mov.avg <- ma(values, 1, 10, FALSE)

numSwaps <- 1000    
mov.avg.swp <- matrix(0, nrow=numSwaps, ncol=length(mov.avg))

# The swapping may take a while, so we display a progress bar 
prog <- txtProgressBar(0, numSwaps, style=3)

for (i in 1:numSwaps)
{
# Swap the data
val.swp <- sample(values)
# Calculate the moving average
mov.avg.swp[i,] <- ma(val.swp, 1, 10, FALSE)
setTxtProgressBar(prog, i)
}

# Now find the 1% and 5% quantiles for each column
limits.1 <- apply(mov.avg.swp, 2, quantile, 0.01, na.rm=T)
limits.5 <- apply(mov.avg.swp, 2, quantile, 0.05, na.rm=T)

# Plot the limits
points(limits.5, t="l", col="orange", lwd=2)
points(limits.1, t="l", col="red", lwd=2)

Esto solo le permitirá encontrar gráficamente las regiones, pero puede encontrarlas fácilmente usando algo en la línea de which(values>limits.5).

nico
fuente
Obviamente, puede aplicar el mismo enfoque utilizando algo más que la media móvil, esto fue solo para dar una idea.
nico
+1 Muchas gracias, nico. Déjame ver si te entendí bien: al final, esto es básicamente como establecer un umbral global y definir cualquier punto con valor <umbral como parte de un valle. El muestreo, etc., solo se utiliza para obtener alguna medida significativa (cuantil) para establecer el umbral. ¿Por qué no podemos usar un solo umbral para todos los puntos? Quiero decir, si hiciéramos suficientes simulaciones obtendríamos líneas rectas (leídas y amarillas). Además, corríjame si me equivoco, pero esto no tiene en cuenta el entorno circundante sino que examina el valor absoluto de cada punto.
David B
@David B: por supuesto, podría usar un umbral global y eso probablemente le ahorraría algo de tiempo de cálculo. Supongo que elegir algo así como 1/3 de la media global podría ser un comienzo. Este proceso de intercambio probablemente sea más útil si utiliza otras estadísticas distintas del promedio móvil, principalmente para dar una idea. De todos modos, la media móvil tendrá en cuenta el entorno, en el ejemplo tendrá en cuenta una ventana de 10 puntos.
nico
4

Soy completamente ignorante de estos datos, pero suponiendo que los datos estén ordenados (no a tiempo, sino por posición), tiene sentido utilizar métodos de series de tiempo. Existen muchos métodos para identificar grupos temporales en los datos. Generalmente se usan para encontrar valores altos, pero se pueden usar para valores bajos agrupados. Estoy pensando en las estadísticas de escaneo, las estadísticas de suma acumulativa (y otras) utilizadas para detectar brotes de enfermedades en los datos de conteo. Ejemplos de estos métodos están en el paquete de vigilancia y el paquete DCluster.


fuente
@cxr Gracias por su respuesta. He echado un vistazo surveillancey DCluster , pero ¿podría ser un poco más específico? Ambos son paquetes relativamente grandes y su objetivo parece bastante específico. No estoy seguro de por dónde empezar.
David B
2

Hay muchas opciones para esto, pero una buena: puede usar la msExtremafunción en el msProcesspaquete .

Editar:

En el análisis del desempeño financiero, este tipo de análisis a menudo se realiza utilizando un concepto de "reducción". El PerformanceAnalyticspaquete tiene algunas funciones útiles para encontrar estos valles . Podría usar el mismo algoritmo aquí si trata sus observaciones como una serie de tiempo.

Aquí hay algunos ejemplos de cómo podría aplicar esto a sus datos (donde las "fechas" son irrelevantes pero solo se usan para ordenar), pero los primeros elementos en el zooobjeto serían sus datos:

library(PerformanceAnalytics)
x <- zoo(cumsum(rnorm(50)), as.Date(1:50))
findDrawdowns(x)
table.Drawdowns(x)
chart.Drawdown(x)
Shane
fuente
Gracias Shane, pero esto parece encontrar mínimos locales (o máximos), es decir, un solo punto en una región. Mis datos (como cualquier dato biológico) SON RUIDO> Realmente no me importan los puntos mínimos en sí mismos, sino las regiones más grandes que son bajas.
David B
Si tiene puntos máximos y mínimos locales, puede calcular fácilmente las diferencias. Entonces, ¿quieres saber los casos en que las diferencias son grandes en magnitud y en "duración"? ¿Son estos datos de series de tiempo?
Shane
@david Quizás, pueda usar esta función de forma iterativa. Usa la función para identificar un mínimo. Suelte ese punto y los puntos circundantes (digamos x puntos dentro de cierto nivel de tolerancia). Puede elegir un nivel de tolerancia (por ejemplo, + - 10 recuentos) que definiría una región plana para su aplicación. Encuentre un nuevo mínimo en el nuevo conjunto de datos. ¿Eso funcionará?
@shane La analogía que viene a la mente es la de los valles en una región montañosa. Creo que el objetivo es identificar todos los valles y el problema es que algunos valles son "más profundos" y otros son "poco profundos" en relación con las montañas.
@Shane No es una serie temporal, estas se coordinan a lo largo del genoma (cromosoma).
David B
2

Algunos de los Bioconductor paquetes 's (por ejemplo, ShortRead , Biostrings , BSgenome , IRanges , genomeIntervals ) ofrecen instalaciones para el tratamiento de posiciones del genoma o vectores de cobertura, por ejemplo, para el chip-ss y la identificación de regiones enriquecidas. En cuanto a las otras respuestas, estoy de acuerdo en que cualquier método que se base en observaciones ordenadas con algún filtro basado en el umbral permitiría aislar la señal baja dentro de un ancho de banda específico.

Quizás también pueda ver los métodos utilizados para identificar las llamadas "islas"

Zang, C, Schones, DE, Zeng, C, Cui, K, Zhao, K y Peng, W (2009). Un enfoque de agrupamiento para la identificación de dominios enriquecidos a partir de datos de modificación de histonas ChIP-Seq . Bioinformática, 25 (15) , 1952-1958.

chl
fuente