Como procurar vales em um gráfico?

10

Estou examinando alguns dados de cobertura genômica, que são basicamente uma longa lista (alguns milhões de valores) de números inteiros, cada um dizendo quão bem (ou "profunda") essa posição no genoma é coberta.

Gostaria de procurar "vales" nesses dados, ou seja, regiões que são significativamente "mais baixas" do que o ambiente circundante.

Observe que o tamanho dos vales que estou procurando pode variar de 50 bases a alguns milhares.

Que tipo de paradigma você recomendaria usar para encontrar esses vales?

ATUALIZAR

Alguns exemplos gráficos para os dados: texto alternativo texto alternativo

ATUALIZAÇÃO 2

Definir o que é um vale é, obviamente, uma das questões com as quais estou lutando. Estes são óbvios para mim: texto alternativo texto alternativo

mas há algumas situações mais complexas. Em geral, existem três critérios que considero: 1. A cobertura (média? Máxima?) Na janela em relação à média global. 2. A (...) cobertura na janela em relação ao seu entorno imediato. 3. Qual é o tamanho da janela: se vejo uma cobertura muito baixa por um curto período, é interessante; se vejo uma cobertura muito baixa por um longo período, também é interessante; se vejo uma cobertura levemente baixa por um curto período, não é realmente interessante. , mas se eu vir uma cobertura levemente baixa por um longo período - é .. Portanto, é uma combinação do comprimento do sapn e da cobertura. Quanto mais tempo, mais alto deixo a cobertura e ainda a considero um vale.

Obrigado,

Dave

David B
fonte
Você poderia fornecer uma pequena amostra de dados?
Shane
@Shane see update
David B
@ David Obrigado. Como as duas respostas sugerem, a análise de séries temporais pode ser aplicada aqui desde que você solicitou observações.
Shane
É meio difícil de responder sem saber exatamente o que você está procurando. Você pode circular os pontos nas parcelas que deseja capturar? O que você considera um "vale"? quão baixo tem que ir e o que você está procurando retornar? É difícil formular uma solução sem conhecer a pergunta, ou seja, limites e tal.
Falmarri 24/09/10
@ Shane ♦ Obrigado. Como também não tenho experiência com análise de séries temporais, você poderia deixar algumas dicas de onde devo começar?
David B

Respostas:

5

Você pode usar algum tipo de abordagem de Monte Carlo, usando, por exemplo, a média móvel de seus dados.

Faça uma média móvel dos dados, usando uma janela de tamanho razoável (acho que depende de você decidir a largura).

Os dados de seus dados (é claro) serão caracterizados por uma média mais baixa, então agora você precisa encontrar um "limite" para definir "baixo".

Para fazer isso, você troca aleatoriamente os valores dos seus dados (por exemplo, usando sample() ) e recalcula a média móvel dos dados trocados.

Repita esta última passagem uma quantidade razoavelmente alta de vezes (> 5000) e armazene todas as médias dessas tentativas. Então, basicamente, você terá uma matriz com 5000 linhas, uma por tentativa, cada uma contendo a média móvel dessa tentativa.

Nesse ponto, para cada coluna, você escolhe o quantil de 5% (ou 1% ou o que quiser), ou seja, o valor sob o qual repousa apenas 5% da média dos dados aleatórios.

Agora você tem um "limite de confiança" (não tenho certeza se esse é o termo estatístico correto) para comparar seus dados originais. Se você encontrar uma parte dos seus dados inferior a esse limite, poderá chamar isso de "a through".

É claro, tenha em mente que nem esse nem qualquer outro método matemático poderia lhe dar qualquer indicação de significado biológico, embora eu tenha certeza de que você está ciente disso.

EDIT - um exemplo

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)

Isso permitirá que você encontre graficamente as regiões, mas você pode encontrá-las facilmente usando algo nas linhas de which(values>limits.5).

nico
fonte
Obviamente, você pode aplicar a mesma abordagem usando algo diferente da média móvel, isso foi apenas para dar uma idéia.
Nico
+1 Muito obrigado, nico. Deixe-me ver se entendi direito: no final, é basicamente como definir um limite global e definir qualquer ponto com valor <threshold como parte de um vale. A amostragem etc. é usada apenas para obter alguma medida significativa (quantil) para definir o limite. Por que não podemos usar um único limite para todos os pontos, quero dizer, se fizéssemos simulações suficientes, obteríamos linhas retas (lidas e amarelas). Além disso, corrija-me se estiver enganado, mas isso não leva em conta o ambiente circundante, mas examina o valor absoluto de cada ponto.
David B
@ David B: é claro, você pode usar um limite global e isso provavelmente poupará algum tempo de cálculo. Eu acho que escolher algo como 1/3 da média global pode ser um começo. Esse processo de troca é provavelmente mais útil se você usar outras estatísticas além da média móvel, principalmente para dar uma idéia. De qualquer forma, a média móvel levará em conta o ambiente, no exemplo, levará em conta uma janela de 10 pontos.
Nico
4

Sou completamente ignorante desses dados, mas supondo que os dados sejam ordenados (não no tempo, mas na posição?), Faz sentido usar métodos de séries temporais. Existem muitos métodos para identificar clusters temporais nos dados. Geralmente eles são usados ​​para encontrar valores altos, mas podem ser usados ​​para valores baixos agrupados. Estou pensando aqui nas estatísticas de varredura, nas estatísticas de soma cumulativa (e outras) usadas para detectar surtos de doenças nos dados de contagem. Exemplos desses métodos estão no pacote de vigilância e no pacote DCluster.


fonte
@cxr Obrigado pela sua resposta. Eu dou uma olhada surveillancee DCluster , mas você poderia ser um pouco mais específico? Ambos são pacotes relativamente grandes e seu objetivo parece bastante específico. Não sei por onde começar.
David B
2

Existem muitas opções para isso, mas uma boa: você pode usar a msExtremafunção no msProcesspacote .

Editar:

Na análise de desempenho financeiro, esse tipo de análise é frequentemente realizado usando um conceito de "levantamento". O PerformanceAnalyticspacote possui algumas funções úteis para encontrar esses vales . Você pode usar o mesmo algoritmo aqui se tratar suas observações como uma série temporal.

Aqui estão alguns exemplos de como você pode aplicar isso aos seus dados (onde as "datas" são irrelevantes, mas usadas apenas para pedidos), mas os primeiros elementos no zooobjeto são seus dados:

library(PerformanceAnalytics)
x <- zoo(cumsum(rnorm(50)), as.Date(1:50))
findDrawdowns(x)
table.Drawdowns(x)
chart.Drawdown(x)
Shane
fonte
Obrigado Shane, mas isso parece encontrar mínimos locais (ou máximos) - ou seja, um único ponto em uma região. Meus dados (como qualquer dado biológico) SÃO BARULHOS> Eu realmente não me importo com mínimos de pontos, mas com regiões maiores que são baixas.
David B
Se você tiver pontos máximos e mínimos locais, poderá calcular facilmente as diferenças. Então você quer saber casos em que as diferenças são grandes em magnitude e em "duração"? São dados de séries temporais?
Shane
@ David Talvez você possa usar iterativamente essa função. Use a função para identificar um mínimo. Solte esse ponto e os pontos circundantes (digamos x pontos dentro de algum nível de tolerância). Você pode escolher um nível de tolerância (por exemplo, + - 10 contagens) que definiria uma região plana para sua aplicação. Encontre um novo mínimo no novo conjunto de dados. Isso vai funcionar?
@shane A analogia que vem à mente é a dos vales em uma região montanhosa. Penso que o objetivo é identificar todos os vales e a questão é que alguns vales são "mais profundos" e outros são "rasos" em relação às montanhas.
@ Shane Não é uma série temporal, estas são coordenadas ao longo do genoma (cromossomo).
David B
2

Alguns dos pacotes do biocondutor (por exemplo, ShortRead , Biostrings , BSgenome , IRanges , genomeIntervals ) oferecem facilidades para lidar com posições de genoma ou vetores de cobertura, por exemplo, para ChIP-seq e identificar regiões enriquecidas. Quanto às outras respostas, concordo que qualquer método baseado em observações ordenadas com algum filtro baseado em limites permitiria isolar o sinal baixo dentro de uma largura de banda específica.

Talvez você também possa examinar os métodos usados ​​para identificar as chamadas "ilhas"

Zang, C, Schones, DE, Zeng, C, Cui, K, Zhao, K e Peng, W (2009). Uma abordagem de agrupamento para identificação de domínios enriquecidos a partir de dados ChIP-Seq de modificação de histonas . Bioinformatics, 25 (15) , 1952-1958.

chl
fonte