26 votos

Decir de una ventana deslizante en R

Tengo un vector de valores que me gustaría informar de la media en windows a lo largo de un menor de diapositivas.

Por ejemplo, para un vector de los valores siguientes:

4, 5, 7, 3, 9, 8

Un tamaño de ventana de 3 y un tobogán de 2 haría lo siguiente:

(4+5+7)/3 = 5.33
(7+3+9)/3 = 6.33
(9+8)/3 = 5.67

Y devuelva un vector de estos valores:

5.33, 6.33, 5.67

Hay una simple función que va a hacer esto por mí? Si también devuelve los índices de la ventana comienza lo que sería un valor añadido. En este ejemplo sería 1,3,5

16voto

Dan Polites Puntos 2649

Rollapply funciona muy bien con un pequeño conjunto de datos. Sin embargo, si usted está trabajando con varios millones de filas (genómica) es bastante lento.

La siguiente función es súper rápido.

data <- c(runif(100000, min=0, max=.1),runif(100000, min=.05, max=.1),runif(10000, min=.05, max=1), runif(100000, min=0, max=.2))

slideFunct <- function(data, window, step){
  total <- length(data)
  spots <- seq(from=1, to=(total-window), by=step)
  result <- vector(length = length(spots))
  for(i in 1:length(spots)){
    result[i] <- mean(data[spots[i]:(spots[i]+window)])
  }
  return(result)
}

http://coleoguy.blogspot.com/2014/04/sliding-window-analysis.html

5voto

travis Puntos 14676

Esta simple línea de código no quiere la cosa:

((c(x,0,0) + c(0,x,0) + c(0,0,x))/3)[3:(length(x)-1)]

si x es el vector en cuestión.

4voto

Akira Puntos 1061

Puedo hacer esto fácilmente en Matlab y el pato mientras downvote mí:

%given vector x, windowsize, slide 
idx1 = 1:slide:numel(x);
idx2 = min(numel(x) + 1,idx1 + windowsize);  %sic on +1 here and no -1;
cx = [0;cumsum(x(:))];  %pad out a zero, perform a cumulative sum;
rv = (cx(idx2) - cx(idx1)) / windowsize; %tada! the answer!

como efecto secundario, idx1 es el índice del elemento en la suma. Estoy seguro de que esto puede ser fácilmente traducido a R. El modismo first:skip:last en Matlab da la matriz primero,+skip, first+2skip, ..., first + n salta, donde el último elemento de la matriz no es mayor que last.

edit: me había omitido en el cálculo de la parte (dividir por windowsize).

3voto

ESRogs Puntos 1381

shabbychef la respuesta en R:

slideMean<-function(x,windowsize=3,slide=2){
 idx1<-seq(1,length(x),by=slide);
 idx1+windowsize->idx2;
 idx2[idx2>(length(x)+1)]<-length(x)+1;
 c(0,cumsum(x))->cx;
 return((cx[idx2]-cx[idx1])/windowsize);
}

EDIT: Índices que estás buscando son sólo idx1... esta función puede ser fácilmente modificado para volver a ellos también, pero es casi igual de rápido que volver a crearlos con otra llamada a seq(1,length(x),by=slide).

1voto

Dillie-O Puntos 16780

De esta manera se consigue que la ventana de medios y el índice del primer valor de la ventana:

#The data
x <- c(4, 5, 7, 3, 9, 8)

#Set window size and slide
win.size <- 3
slide <- 2

#Set up the table of results
results <- data.frame(index = numeric(), win.mean = numeric())

#i indexes the first value of the window (the sill?)
i <- 1
#j indexes the row of the results to be added next
j <- 1
while(i < length(x)) {
    #This mean preserves the denominator of 3
    win.mean <- sum(x[i:(i+2)], na.rm = TRUE)/win.size
    #Insert the results
    results[j, ] <- c(i, win.mean)
    #Increment the indices for the next pass
    i <- i + slide
    j <- j + 1
    }

Varias cuestiones se aplican: no he probado esto en contra de nada, pero el ejemplo de los datos; creo que anexar a las tramas de datos como esto puede ser muy lento si usted tiene un montón de valores (porque va a copiar los datos.fotograma cada vez); etc. Pero lo que no produce lo que usted pidió.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X