Есть ли способ выполнить rollapply/rollsum для вычисления сумм строк в матрице редкий по окнам фиксированной длины? Я работаю с dgTMatrix для удобства, но моя проблема не относится к этому классу. Например, рассмотрите возможность создания разреженной матрицы 8 x 10.
library(Matrix)
i <- c(1,3:8); j <- c(2,9,6:10); x <- 7 * (1:7)
A <- sparseMatrix(i, j, x = x, giveCsparse = FALSE)
> A
8 x 10 sparse Matrix of class "dgTMatrix"
[1,] . 7 . . . . . . . .
[2,] . . . . . . . . . .
[3,] . . . . . . . . 14 .
[4,] . . . . . 21 . . . .
[5,] . . . . . . 28 . . .
[6,] . . . . . . . 35 . .
[7,] . . . . . . . . 42 .
[8,] . . . . . . . . . 49
Без предварительного приведения к матрице (например, as.matrix()) один наивный подход использует sapply для вычисления суммы строк по каждому window=2 столбцу, в результате чего получается матрица 8 x 5плотный.
window = 2
starts = seq(1,dim(A)[2],by=window)
A_rollsum <- sapply(starts, function(x) Matrix::rowSums(A[, x:(x+window-1)]))
> A_rollsum
[,1] [,2] [,3] [,4] [,5]
[1,] 7 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 14
[4,] 0 0 21 0 0
[5,] 0 0 0 28 0
[6,] 0 0 0 35 0
[7,] 0 0 0 0 42
[8,] 0 0 0 0 49
Это неэффективно для больших разреженных матриц.
Матрицы не идентичны A_rollsum. Я отредактировал вопрос, чтобы отразить, как должны выглядеть A и A_rollsum.
Ваш код A_rollsum не работает, так как by.column не использовался. Я переместил свои комментарии в ответ и показываю, что два способа вычисления результата одинаковы.
Я не хотел сказать, что последние два A_rollsum должны давать правильную матрицу. Правильный вывод — с sapply, но я бы хотел использовать что-то вроде rollapply. Я удалю последние два, чтобы избежать путаницы.
OK. Я пересмотрел его с плотным и разреженным ответом.





1)rollapply работает столбец за столбцом, и, очевидно, вы хотите построчно, поэтому транспонируйте его, используйте rollapply, как показано, и транспонируйте обратно:
t(rollapply(t(as.matrix(A)), 2, by = 2, sum))
давая:
[,1] [,2] [,3] [,4] [,5]
[1,] 7 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 14
[4,] 0 0 21 0 0
[5,] 0 0 0 28 0
[6,] 0 0 0 35 0
[7,] 0 0 0 0 42
[8,] 0 0 0 0 49
2) В приведенном выше примере используются плотные матрицы, но если вам действительно нужны разреженные матрицы, обратите внимание, что rollapply здесь является линейным оператором, поэтому мы можем вычислить его матрицу, а затем использовать умножение разреженных матриц.
d <- rollapply(diag(10), 2, by = 2, sum)
A %*% t(d)
Вопрос был изменен. это ответ на исходный вопрос.
Попробуйте r1. Покажем, что оно равно r2.
r1 <- rollapply(rowSums(A), 3, c)
r2 <- rollapply(as.matrix(A), 3, rowSums, by.column = FALSE)
identical(r1, r2)
## [1] TRUE
r1 и, следовательно, также r2 равно:
> r1
[,1] [,2] [,3]
[1,] 7 0 14
[2,] 0 14 21
[3,] 14 21 28
[4,] 21 28 35
[5,] 28 35 42
[6,] 35 42 49
@ G.Grothendieck - Есть ли способ не принуждать его к стандарту
matrix?