R spdep гигантский вес матрицы
Я новичок в пространственной статистике, и я пытаюсь создать пространственную матрицу весов для всех участков переписи в США в R. Есть около 74000 участков.
Основываясь на Tiger Files США переписи, я создал шейп-файл всех трактатов, а затем сделал (используя spdep
упаковка):
#Create adjacency matrix
am = poly2nb(us)
is.symmetric.nb(am)
Это прекрасно работает, хотя я довольно большой.
Следующий:
am = nb2mat(am, style="B",zero.policy=T)
Что дает мне эту ошибку:
Error: cannot allocate vector of size 40.9 Gb
Очевидно, мой ноутбук не может обрабатывать 40,9 ГБ памяти. Я пытался сделать это в облаке AWS EC2, но чтобы получить столько памяти, мне нужно было получить очень большой экземпляр, которого я бы хотел избежать, поскольку я совершенно новичок в облачных вычислениях и предпочел бы играть в бесплатном T2. микро песочница (максимум до 1 ГиБ памяти), пока я не буду готов потратить немного денег на большую машину. Если бы я мог превратить матрицу весов в разреженную матрицу, я бы справился с этим, но я не знаю, как это сделать. Я пытался сделать что-то вроде этого:
Wmat<-Matrix(nb2mat(am, style="B",zero.policy=T),sparse=TRUE)
Но ему все еще требуется вся память для выполнения команды nb2mat перед созданием разреженной матрицы.
Какие-либо решения?
1 ответ
Конечно, уже немного поздно. Но я думаю, что я только что нашел решение. У меня похожая ситуация с матрицей 71k*71k.
Я только что переработал функцию nb2mat, чтобы использовать big.matrix из библиотеки bigmemory. Нам нужно определить две новые функции:
my_nb2mat = function (neighbours, glist = NULL, style = "W", zero.policy = NULL)
{
if (is.null(zero.policy))
zero.policy <- get("zeroPolicy", envir = .spdepOptions)
stopifnot(is.logical(zero.policy))
if (!inherits(neighbours, "nb"))
stop("Not a neighbours list")
listw <- nb2listw(neighbours, glist = glist, style = style,
zero.policy = zero.policy)
res <- my_listw2mat(listw)
attr(res, "call") <- match.call()
res
}
my_listw2mat = function (listw)
{
require(bigmemory)
n <- length(listw$neighbours)
if (n < 1)
stop("non-positive number of entities")
cardnb <- card(listw$neighbours)
if (any(is.na(unlist(listw$weights))))
stop("NAs in general weights list")
#res <- matrix(0, nrow = n, ncol = n)
res <- big.matrix(n, n, type='double', init=NULL)
options(bigmemory.allow.dimnames=TRUE)
for (i in 1:n) if (cardnb[i] > 0)
res[i, listw$neighbours[[i]]] <- listw$weights[[i]]
if (!is.null(attr(listw, "region.id")))
row.names(res) <- attr(listw, "region.id")
res
}
Вызовите новую функцию my_nb2mat здесь:
a=my_nb2mat(neighbours = out, style='W',zero.policy =F )
Примечание: библиотека bigmemory для меня работает только в R\R-2.15.3.