эффективный способ хранения списков в рамках датафрейма - PullRequest
0 голосов
/ 27 января 2020

Мне нужно иметь возможность вычислять попарно пересечение списков, близких к 40К. В частности, я хочу знать, могу ли я сохранить идентификатор вектора в виде столбца 1 и список его значений в столбце 2. Я должен быть в состоянии обработать этот столбец 2, ie найти перекрытия / пересечения между двумя строками.

column 1  column 2
idA       1,2,5,9,10
idB       5,9,25
idC       2,25,67

Я хочу иметь возможность получить значения парных пересечений, а также, если значения в столбце 2 еще не отсортированы, это также должно быть возможно.

Какова лучшая структура данных, которую я можно использовать, если я иду с R? Мои данные изначально выглядят так:

column1 1 2 3 9 10 25 67 5
idA     1 1 0 1  1  0  0 1
idB     0 0 0 1  0  1  0 1
idC     0 1 0 0  0  1  1 0

отредактировано, чтобы включить больше ясности в соответствии с предложениями ниже.

1 Ответ

1 голос
/ 27 января 2020

Я бы сохранил данные в логической матрице:

DF <- read.table(text = "column1 1 2 3 9 10 25 67 5
idA     1 1 0 1  1  0  0 1
idB     0 0 0 1  0  1  0 1
idC     0 1 0 0  0  1  1 0", header = TRUE, check.names = FALSE)

#turn into logical matrix
m <- as.matrix(DF[-1])
rownames(m) <- DF[[1]]
mode(m) <- "logical"

#if you can, create your data as a sparse matrix to save memory
#if you already have a dense data matrix, keep it that way
library(Matrix)
M <- as(m, "lMatrix")

#calculate intersections 
#does each comparison twice
intersections <- simplify2array(
  lapply(seq_len(nrow(M)), function(x) 
    lapply(seq_len(nrow(M)), function(x, y) colnames(M)[M[x,] & (M[x,] == M[y,])], x = x)
  )
)

Этот двойной l oop можно оптимизировать. Я сделал бы это в R cpp и создал бы длинный формат data.frame вместо матрицы списка. Я бы также делал каждое сравнение только один раз (например, только верхний треугольник).

colnames(intersections) <- rownames(intersections) <- rownames(M)
#    idA         idB         idC        
#idA Character,5 Character,2 "2"        
#idB Character,2 Character,3 "25"       
#idC "2"         "25"        Character,3

intersections["idA", "idB"]
#[[1]]
#[1] "9" "5"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...