2015-12-14 4 views
3

Я бегу R 3.2.3 на машине с 128 ГБ ОЗУ. У меня есть большая матрица из 123028 строк х 168 столбцов. Я хотел бы использовать иерархический алгоритм кластеризации в R, поэтому, прежде чем я это сделаю, я пытаюсь создать матрицу расстояний в R, используя функцию vegdist() в пакете vegan с помощью метода Bray-Curtis. Я получаю ошибку о распределении памяти:R большая матрица расстояния в вегане

df <- as.data.frame(matrix(rnorm(20668704), nrow = 123028)) 
library(vegan) 
mydist <- vegdist(df) 

Ошибка в vegdist (DF): длинные векторы (аргумент 4) не поддерживаются в .Fortran

Если я использую пакет pryr для узнайте, сколько памяти требуется для матрицы расстояния, я вижу, что требуется 121 ГБ, что меньше, чем у ОЗУ, которое у меня есть.

library(pryr) 
mem_change(x <- 1:123028^2) 

121 GB

Я знаю, что раньше предел 2 млрд значений для одного объекта в R, но я думал, что предел исчез в последних версиях R. Есть другой лимит памяти, о котором я не знаю?

Суть в том, что мне интересно: что я могу сделать с этой ошибкой? Действительно ли это из-за ограничений памяти или я ошибаюсь? Я хотел бы остаться в R и использовать алгоритм кластеризации помимо k-средств, поэтому мне нужно вычислить матрицу расстояний.

+0

Вы всегда можете вычислить его кусочно. –

ответ

4

R может обрабатывать длинные векторы просто отлично, но кажется, что вычисление матрицы расстояний реализовано в C или Fortran и сопряжено с R с использованием .C или .Fortran, которые не принимают длинные векторы (т.е. векторы длиной> 2^32 -1) в качестве аргументов. Смотрите документацию here, в котором говорится:

Обратите внимание, что интерфейсы .C и .Fortran не принимают длинных векторов, так .call (или аналогичный), должен быть использован.

Глядя на source code для функции vegdist(), это выглядит как ваша матрица преобразуется в вектор, а затем передается в функцию, реализованной в C для вычисления расстояния. Соответствующие строки кода:

d <- .C("veg_distance", x = as.double(x), nr = N, nc = ncol(x), 
     d = double(N * (N - 1)/2), diag = as.integer(FALSE), 
     method = as.integer(method), NAOK = na.rm, PACKAGE = "vegan")$d 

И в этом ваша проблема. Когда ваша матрица отлита от вектора, она становится длинным вектором, который не поддерживается .C. Вам придется искать другой пакет, чтобы вычислить вашу матрицу расстояний (или реализовать ее самостоятельно).

+0

Спасибо! Это ответило на вопрос, почему я получаю сообщение об ошибке. Мой следующий вопрос - что я могу сделать с этим? Я могу попытаться сделать это кусочно, как предложил Алекс выше, но существуют ли какие-либо другие существующие функции, которые будут вычислять расстояние Брей-Кертиса на более крупной матрице? – jk22

+0

@ jk22 В качестве первого шага вам следует обратиться к веганским авторам. Они очень полезны в моем опыте и могут найти решение, которое может быть включено в будущие версии vegan. – Tyler

+0

@ jk22 Выполнение быстрого поиска google дает пакет [ecodist] (https://cran.r-project.org/web/packages/ecodist/), который имеет функцию 'bcdist()' для вычисления расстояний Bray-Curtis. Я не уверен, обрабатывает ли он более крупные матрицы или нет. – ialm