R: janela deslizante rápida com coordenadas dadas
Eu tenho uma tabela de dados com nrow sendo em torno de um milhão ou dois e ncol de cerca de 200.
Cada entrada em uma linha tem uma coordenada associada a ela.
Porção minúscula dos dados:
[1,] -2.80331471 -0.8874522 -2.34401863 -3.811584 -2.1292443
[2,] 0.03177716 0.2588624 0.82877467 1.955099 0.6321881
[3,] -1.32954665 -0.5433407 -2.19211837 -2.342554 -2.2142461
[4,] -0.60771429 -0.9758734 0.01558774 1.651459 -0.8137684
Coordenadas para as primeiras 4 linhas:
9928202 9928251 9928288 9928319
O que eu gostaria é uma função que, dado os dados e o tamanho da janela, retornaria uma tabela de dados do mesmo tamanho com uma janela deslizante média aplicada em cada coluna. Ou em outras palavras - para cada entrada de linhai ele encontraria entradas com coordenadas entre coords [i] -windsize e coords [i] + windsize e substituiria o valor inicial pela média dos valores dentro desse intervalo (separadamente para cada coluna).
A velocidade é o principal problema aqui.
Aqui está o meu primeiro exame de tal função.
doSlidingWindow <- function(intensities, coords, windsize) {
windHalfSize <- ceiling(windsize/2)
### whole range inds
RANGE <- integer(max(coords)+windsize)
RANGE[coords] <- c(1:length(coords)[1])
### get indeces of rows falling in each window
COORDS <- as.list(coords)
WINDOWINDS <- sapply(COORDS, function(crds){ unique(RANGE[(crds-windHalfSize):
(crds+windHalfSize)]) })
### do windowing
wind_ints <- intensities
wind_ints[] <- 0
for(i in 1:length(coords)) {
wind_ints[i,] <- apply(as.matrix(intensities[WINDOWINDS[[i]],]), 2, mean)
}
return(wind_ints)
}
O código antes do último loop for é bastante rápido e me fornece uma lista dos índices que eu preciso usar para cada entrada. No entanto, tudo se desmonta, pois preciso moer o loop for um milhão de vezes, obter subconjuntos da minha tabela de dados e também certificar-me de que possuo mais de uma linha para poder trabalhar com todas as colunas de uma só vez.
Minha segunda abordagem é apenas colocar os valores reais na lista RANGE, preencher as lacunas com zeros e rollmean do pacote zoo, repetidos para cada coluna. Mas isso é redundante, já que o rollmean passará por todas as lacunas e eu só usarei os valores das coordenadas originais no final.
Qualquer ajuda para torná-lo mais rápido sem ir para C seria muito apreciada.