Скользящая медиана с построением подмножества с течением времени

Я хотел бы вычислить вариант скользящих медиан в моем наборе данных, который строит подмножества не путем k наблюдений вперед и назад, а с учетом всех наблюдений, которые находятся в данном временном окне.

Простая реализация может выглядеть так:

windowwidth <- 30
median.window <- function(x) median(mydata[time <= x + windowwidth /2 & time >= x - windowwidth /2)
vapply(time, median.window)

Однако, как вы понимаете, это не очень эффективно для больших наборов данных. Видите ли вы возможное улучшение или пакет, обеспечивающий оптимизированную реализацию? Нельзя ожидать, что наблюдения будут равномерно распределены во времени.

zoo предоставляет rollmedian, но эта функция предлагает выбрать окно не по времени, а по количеству наблюдений.


person Thilo    schedule 13.12.2011    source источник
comment
Если вы добавите набор данных об игрушках, это поможет повысить интерес. См. Также этот вопрос   -  person Joris Meys    schedule 13.12.2011
comment
Поскольку временная метка для каждого наблюдения по существу, исходя из вашего описания, случайна, не существует априорного способа определить, какие наблюдения вписываются в данное окно. Тем не менее, мне интересно, может ли использование outer() с подходящей функцией временного типа по крайней мере построить вам полный набор оконных наборов образцов. Мне придется пойти и поиграть с этим.   -  person Carl Witthoft    schedule 13.12.2011


Ответы (1)


Хорошо, попробуйте это:

Rgames: timeseq<-1:5 
Rgames: winmat <- outer(timeseq,timeseq,FUN=function(x,y) y>=x &y<=x+2) 
Rgames: winmat 
      [,1]  [,2]  [,3]  [,4]  [,5] 
[1,]  TRUE  TRUE  TRUE FALSE FALSE 
[2,] FALSE  TRUE  TRUE  TRUE FALSE 
[3,] FALSE FALSE  TRUE  TRUE  TRUE 
[4,] FALSE FALSE FALSE  TRUE  TRUE 
[5,] FALSE FALSE FALSE FALSE  TRUE 
Rgames: winmat %*% timeseq 
     [,1] 
[1,]    6 
[2,]    9 
[3,]   12 
[4,]    9 
[5,]    5 

Замените эту функцию шириной окна, и я думаю, у вас все будет готово.
Изменить: В ответ на запрос Тило, похоже, в общем случае вам следует использовать apply. Учитывая вышеизложенное, назовите свои значения наблюдений "timval", как

Rgames: timval<-c(3,4,2,6,1)
Rgames: valmat<-timval*t(winmat)
Rgames: valmat
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    0    0    0    0
[2,]    4    4    0    0    0
[3,]    2    2    2    0    0
[4,]    0    6    6    6    0
[5,]    0    0    1    1    1
Rgames: apply(valmat,2,median)
[1] 2 2 1 0 0

Отредактируйте еще раз: очевидно, я спал там: никому не нужна медиана, основанная на всех этих нулях. Я должен подумать больше, прежде чем публиковать. Добавь это:

valmat[valmat==0]<- NA
apply(valmat,2, median, na.rm=T)
[1] 3.0 4.0 2.0 3.5 1.0

И я уверен, что есть более чистый способ «построения» valmat, чем этот, но конечным результатом является «матрица фильтров», к которой вы хотите применить любую функцию.

person Carl Witthoft    schedule 13.12.2011
comment
+1 - Очень красиво. Я всегда ценю элегантность решений на основе outer! (Кстати, надеюсь, вы не возражаете против моего редактирования вашего ответа. Я сделал это только потому, что знал, что вы можете изменить его обратно, если вы это сделаете.) - person Josh O'Brien; 13.12.2011
comment
Хммм - все, что вы редактировали, не сразу видно невооруженному глазу :-), так что я вряд ли могу жаловаться. - person Carl Witthoft; 13.12.2011
comment
Если вам когда-либо будет интересно посмотреть на правки, вы можете увидеть их, щелкнув ссылку «отредактировано X час / день назад» над именем редактора (здесь Джош О'Брайен). Ваше здоровье. - person Josh O'Brien; 13.12.2011
comment
Спасибо, Карл. Однако как я могу получить медианное значение на основе этого решения? Я понимаю, как вычислять скользящие средние, но в отношении медиан я сначала подумал, что мне все равно придется использовать одну из функций apply, теперь с предварительно вычисленными фильтрами. Вы имели в виду другую идею? - person Thilo; 13.12.2011