R: función de ventana móvil con ventana ajustable y tamaño de paso para observaciones espaciadas irregularmente

Digamos que hay un marco de datos de 2 columnas con una columna de tiempo o distancia que aumenta secuencialmente y una columna de observación que puede tener NA aquí y allá. ¿Cómo puedo usar eficientemente una función de ventana deslizante para obtener alguna estadística, digamos una media, para las observaciones en una ventana de duración X (por ejemplo, 5 segundos), deslice la ventana sobre Y segundos (por ejemplo, 2.5 segundos), repita ...El número de observaciones en la ventana se basa en la columna de tiempo, por lo tanto, tanto el número de observaciones por ventana como el número de observaciones para deslizar la ventana pueden variar. La función debe aceptar cualquier tamaño de ventana hasta el número de observaciones y un tamaño de paso.

Aquí hay datos de muestra (ver "Editar:"para un conjunto de muestra más grande)

set.seed(42)
dat <- data.frame(time = seq(1:20)+runif(20,0,1))
dat <- data.frame(dat, measure=c(diff(dat$time),NA_real_))
dat$measure[sample(1:19,2)] <- NA_real_
head(dat)
      time   measure
1 1.914806 1.0222694
2 2.937075 0.3490641
3 3.286140        NA
4 4.830448 0.8112979
5 5.641746 0.8773504
6 6.519096 1.2174924

Salida deseada&nbsp;para el caso específico de una ventana de 5 segundos, paso de 2.5 segundos, primera ventana de -2.5 a 2.5, na.rm = FALSO:

 [1] 1.0222694
 [2]        NA
 [3]        NA
 [4] 1.0126639
 [5] 0.9965048
 [6] 0.9514456
 [7] 1.0518228
 [8]        NA
 [9]        NA
[10]        NA

Explicación: En la salida deseada, la primera ventana busca tiempos entre -2.5 y 2.5. Una observación de medida se encuentra en esta ventana, y no es una NA, por lo que obtenemos esa observación: 1.0222694. La siguiente ventana es de 0 a 5, y hay un NA en la ventana, por lo que obtenemos NA. Lo mismo para la ventana de 2.5 a 7.5. La siguiente ventana es de 5 a 10. Hay 5 observaciones en la ventana, ninguna es NA. Entonces, obtenemos el promedio de esas 5 observaciones (es decir, media (dat [dat $ time> 5 y dat $ time <10, 'measure']))

Lo que probé:&nbsp;Esto es lo que probé para el caso específico de una ventana donde el tamaño del paso es la mitad de la duración de la ventana:

windo <- 5  # duration in seconds of window

# partition into groups depending on which window(s) an observation falls in
# When step size >= window/2 and < window, need two grouping vectors
leaf1 <- round(ceiling(dat$time/(windo/2))+0.5)
leaf2 <- round(ceiling(dat$time/(windo/2))-0.5) 

l1 <- tapply(dat$measure, leaf1, mean)
l2 <- tapply(dat$measure, leaf2, mean)

as.vector(rbind(l2,l1))

No flexible, no elegante, no eficiente. Si el tamaño del paso no es 1/2 tamaño de ventana, el enfoque no funcionará, tal como está.

¿Alguna idea sobre una solución general a este tipo de problema? Cualquier solución es aceptable. Cuanto más rápido, mejor, aunque prefiero soluciones que usen base R, data.table, Rcpp y / o computación paralela. En mi conjunto de datos reales, hay varios millones de observaciones contenidas en una lista de marcos de datos (el marco de datos máximo es ~ 400,000 observaciones).

A continuación hay una información adicional: un conjunto de muestra más grande

Editar:&nbsp;Según la solicitud, aquí hay un conjunto de datos de ejemplo más grande y realista con muchos más NA y el período de tiempo mínimo (~ 0.03). Sin embargo, para ser claros, la lista de marcos de datos contiene pequeños como el anterior, y otros como los siguientes y más grandes:

set.seed(42)
dat <- data.frame(time = seq(1:50000)+runif(50000, 0.025, 1))
dat <- data.frame(dat, measure=c(diff(dat$time),NA_real_))
dat$measure[sample(1:50000,1000)] <- NA_real_
dat$measure[c(350:450,3000:3300, 20000:28100)] <- NA_real_
dat <- dat[-c(1000:2000, 30000:35000),] 

# a list with a realistic number of observations:
dat <- lapply(1:300,function(x) dat)