2015-03-09 1 views
1

У меня есть R редкая матрица (очень большая, невозможная для преобразования в полную матрицу), я хочу идентифицировать/исключить дубликаты столбцов, если таковые существуют. (x, MARGIN = 2), но работает на разреженных матрицах.R - устранение повторяющихся столбцов в разреженной матрице

есть что-нибудь подобное вокруг? предложения о том, как это сделать?

ответ

0

Я тоже не нашел отличного решения, но это то, что я использовал.

library(data.table) 
DFSummary<-summary(DF) 
DT<-data.table(DFSummary) 
setkey(DT,j) 
nDF<-ncol(DF) 

dupeList<- list() 
dupeList[[nDF]]=NULL 
    for(k in 1:nDF){ 
    dupeList[[k]]<-sort(DT[j==k,i]) 
    if(k%%1000==0) print (k/nDF) 
    } 

dupeVec<-duplicated(dupeList) 
dupes<-which(dupeVec==TRUE) 

Имейте в виду, что это решение будет работать только для двоичной матрицы. Если у вас есть числовая матрица, вы можете сделать что-то вроде вставки индекса i в значение x. Например, DFSummary$ix<-paste(DFSummary$i,DFSummary$x,sep=':'), а затем сохраните значения ix в списке dupeList.

0

Одним из вариантов является использование uniquecombs транспонирования в пакете mgcv, а затем транспонирование матрицы. Функция работает на разреженной матрице, но возвращает плотную матрицу. Это может вызвать проблемы с памятью, если матрица, с которой вы работаете, слишком велика.

set.seed(123) 
n <- 500 
p <- 10/n 
pDup <- 1/100 
DupRow <- sample(c(1, 0), n, prob = c(p, 1-p), replace = TRUE) 
IsDup <- sample(c(1, 0), n, prob = c(pDup, 1-pDup), replace = TRUE) 
sum(IsDup) 
# 5 
myBigMat <- 
    Reduce(cbind2, lapply(IsDup, 
           function(x) { 
            if (x) { 
            toFill <- DupRow 
            } else { 
            toFill <- sample(c(1, 0), n, prob = c(p, 1-p), replace = TRUE) 
            } 
            Matrix(toFill,nrow = n, ncol = 1, sparse = TRUE) 
           } 
           )) 

NoDuplicateCols <- t(Matrix(mgcv::uniquecombs(t(myBigMat)), sparse = TRUE)) 
dim(NoDuplicateCols) 
# 500 496