Метод перемещения окна для агрегирования данных - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть матрица ниже:

 mat<- matrix(c(1,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,
       2,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,
       0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
       0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,
       1,1,0,0,0,0,0,0,1,0,1,2,1,0,0,0), nrow=16, ncol=6)
 dimnames(mat)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
              c("1", "2", "3", "4", "5", "6"))

Мне нужно агрегировать столбцы, используя метод движущегося окна.Во-первых, размер окна будет 2, так что окно состоит из 2 столбцов.Строковые суммы взяты для этой совокупности.Окно сместится на один шаг и снова получит суммы строк.Для предоставленного примера фрейма данных первые столбцы, подлежащие агрегированию, - это столбцы 1 и 2, второе окно объединит столбцы 2 и 3, затем 3 и 4, затем 4 и 5 и 5 и 6.

Эти результаты (суммы строк для каждого агрегата) помещаются в матрицу.В этой матрице строки сохраняются, и столбцы теперь представляют результаты для каждого агрегата.

Затем размер движущегося окна увеличится до 3. Таким образом, 3 столбца данных объединяются (суммируются).Аналогично, окно сдвигается на 1 шаг.Для предоставленного примера фрейма данных первые столбцы, подлежащие агрегированию, - это столбцы 1-2-3, второе окно объединит столбцы 2-3-4, а затем 3-4-5, 4-5-6.Результаты помещаются в отдельную матрицу.

Размер движущегося окна будет увеличиваться до тех пор, пока размер окна не станет размером всех столбцов.В этом примере самое большое окно объединяет все 6 графиков.

Ниже приведены матрицы результатов для размеров окон 2 и 3 с учетом приведенной выше матрицы mat.Столбцы именуются в соответствии с добавленными столбцами.

#Window length =2 
mat1<- matrix( c(3,0,0,0,1,0,1,0,0,0,0,0,0,0,2,0,
         2,0,1,1,2,0,0,0,0,0,0,0,0,0,1,0,
         0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,
         0,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,
         1,1,0,0,1,0,0,1,1,1,2,2,1,1,0,1), nrow=16)
dimnames(mat1)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
              c("1_2", "2_3", "3_4", "4_5", "5_6"))

 #Window length 3
 mat8<- matrix( c(3,0,1,1,2,0,1,0,0,0,0,0,0,0,3,0,
         2,1,1,1,2,1,0,0,0,0,0,0,0,0,1,0,
         0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,
         1,2,0,0,1,1,0,1,1,1,2,2,1,1,0,1), nrow=16)
 dimnames(mat8)<- list(c("a", "c", "f", "h", "i", "j", "l", "m", "p", "q", "s", "t", "u", "v","x", "z"), 
              c("1_2_3", "2_3_4", "3_4_5", "4_5_6"))

В моем примере у меня 6 столбцов, поэтому всего будет 5 матриц результата.В случае, если у меня было 600 столбцов данных, я думаю, что цикл - это самый эффективный способ перебора большого набора данных.

1 Ответ

2 голосов
/ 20 сентября 2019

Вот один из способов в базе R

lapply(seq_len(ncol(mat) - 1), function(j) do.call(cbind, 
   lapply(seq_len(ncol(mat) - j), function(i) rowSums(mat[, i:(i + j)]))))


#[[1]]
#  [,1] [,2] [,3] [,4] [,5]
#a    3    2    0    0    1
#c    0    0    1    1    1
#f    0    1    1    0    0
#h    0    1    1    0    0
#i    1    2    1    1    1
#j    0    0    1    1    0
#l    1    0    0    0    0
#m    0    0    0    1    1
#p    0    0    0    0    1
#q    0    0    0    1    1
#s    0    0    0    1    2
#t    0    0    0    0    2
#u    0    0    0    0    1
#v    0    0    0    1    1
#x    3    1    0    0    0
#z    0    0    0    1    1

#[[2]]
#  [,1] [,2] [,3] [,4]
#a    3    2    0    1
#c    0    1    1    2
#f    1    1    1    0
#h    1    1    1    0
#i    2    2    2    1
#j    0    1    1    1
#l    1    0    0    0
#m    0    0    1    1
#p    0    0    0    1
#q    0    0    1    1
#s    0    0    1    2
#t    0    0    0    2
#u    0    0    0    1
#v    0    0    1    1
#x    3    1    0    0
#z    0    0    1    1
#....

Поскольку это операция прокатки, мы также можем использовать rollapply из zoo с переменной шириной окна

lapply(2:ncol(mat), function(j)
    t(zoo::rollapply(seq_len(ncol(mat)), j, function(x) rowSums(mat[,x]))))
...