Как рассчитать матрицы совместного использования на основе больших фреймов данных? - PullRequest
5 голосов
/ 24 января 2020

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

negative length vectors are not allowed

... или позже, используя base::crossprod

error in crossprod: attempt to make a table with >=2^31 elements

Оба связаны с размером кадра данных. В первом случае это относится к числу строк, а во втором случае размер матрицы превышает предел.

Мне известны решения для первого предложенного вопроса (data.table::melt) по [2] , [3] и [4] , а также по второму выпуску (base::crossprod) по [5] и [6] , и я видел [7] , но я не уверен, как правильно адаптировать их к моей ситуации. Я попытался разбить информационный кадр по идентификатору на несколько информационных кадров, объединить их и вычислить матрицу совместного использования, но я только что выдал дополнительные сообщения об ошибках (например, не могу выделить вектор размером 17,8 ГБ).

Воспроизводимый Пример

У меня есть собранный кадр данных, созданный plyr::join, который выглядит следующим образом (но, конечно, намного больше):

df <- data.frame(ID = c(1,2,3,20000), 
                  C1 = c("England", "England", "England", "China"),
                  C2 = c("England", "China", "China", "England"),
                  C5850 = c("England", "China", "China", "England"),
                  SC1 = c("FOO", "BAR", "EAT", "FOO"),
                  SC2 = c("MERCI", "EAT", "EAT", "EAT"),
                  SC5850 = c("FOO", "MERCI", "FOO", "FOO"))

ID      C1      C2      ... C5850    SC1 SC2   ... SC5850
1       England England     England  FOO MERCI     FOO
2       England China       China    BAR EAT       MERCI
3       England China       China    EAT EAT       EAT
200000  China   England     England  FOO EAT       FOO

Исходный код

colnames(df) <- c(paste0("SCCOUNTRY", 2:7))

library(data.table)

melt(setDT(df), id.vars = "ID", measure = patterns("^SCCOUNTRY"))[nchar(value) > 0 & complete.cases(value)] -> foo
unique(foo, by = c("ID", "value")) -> foo2
crossprod(table(foo2[, c(1,3)])) -> mymat
diag(mymat) <- ifelse(diag(mymat) <= 1, 0, mymat)

Условия (для расчета матрицы совмещения)

  1. Отдельные наблюдения без дополнительных наблюдений по идентификатору / строке не рассматриваются, т.е. Строка, содержащая только одну страну, считается как 0.
  2. Комбинация / совместное вхождение должно учитываться как 1.
  3. Наличие комбинации означает также и самосочетание. (США-США), т. Е. Присваивается значение 1.
  4. Не существует значения свыше 1, назначенного комбинации по строке / идентификатору.
...