Разбить матрицу на подматрицы

Я нашел решение аналогичного вопроса, который разбивает матрицу на набор неперекрывающихся подматриц, когда матрица может быть не квадратной (а в моей ситуации это может быть не так) Функция для разделения матрицы на подматрицы в R. Однако в моем случае я хочу, чтобы матрицы перекрывались. Используя следующую матрицу в качестве примера:

M <- matrix(1:20, 5)

#     [,1] [,2] [,3] [,4]
#[1,]    1    6   11   16
#[2,]    2    7   12   17
#[3,]    3    8   13   18
#[4,]    4    9   14   19
#[5,]    5   10   15   20

Если я выберу количество строк и столбцов подматриц равным 4 и 4 соответственно, то возвращаемые подматрицы должны быть всеми возможными перекрывающимися подматрицами 4X4, которые полностью вписываются в границы исходной матрицы (это еще одно место, где ответ на этот вопрос может отличаться от вопроса, на который я ссылался). В моем примере должны быть возвращены только две субматрицы. M[1:4,1:4] и M[2:5,1:4]. Я должен иметь возможность выбрать любой произвольный размер подматрицы. Кажется, я не могу найти никаких примеров извлечения перекрывающихся субматриц, но, возможно, я слишком много думаю об этом. Есть ли у кого-нибудь идеи, как лучше всего это сделать?


person Beaker    schedule 18.01.2015    source источник


Ответы (1)


Возможно, такая стратегия сработает

submat <- function(m, nrow, ncol) {
    stopifnot(nrow(m)>=nrow, ncol(m)>=ncol)
    rowstarts<-1:(nrow(m)-nrow+1)
    colstarts<-1:(ncol(m)-ncol+1)
    ss <- function(r, c) {
        m[r:(r+nrow-1), c:(c+ncol-1), drop=FALSE]
    }
    with(expand.grid(r=rowstarts, c=colstarts), mapply(ss, r, c, SIMPLIFY=FALSE))
}

submat(M, 4, 4)

мы определяем, где находятся возможные начальные индексы для строк и столбцов, затем мы используем expand.grid() для генерации всех возможных комбинаций таких начальных значений, затем мы используем mapply для извлечения всех возможных подматриц с этими начальными позициями.

person MrFlick    schedule 18.01.2015
comment
Отличный ответ! Мне нужно перестать забывать о expand.grid. - person Beaker; 19.01.2015