Проблемы с foreach () и% dopar% в R - PullRequest
1 голос
/ 18 января 2020

Я пытаюсь выполнить функцию объединения строк для data.tables внутри foreach().

Пока мой код работал с небольшими наборами тестовых наборов данных и подмножеств (100 x 100, 1000 x 1000), но терпит неудачу, когда наборы данных становятся больше (скажем, 4810 x 28950).

Код

library(data.table)
setDTthreads(8)
# Create small case study dataframe (4*6)
x<-data.table("name"=c("11-a>b","11--a>b","12-c>d","12--c>d"),
              "marker"=c(1,1,2,2),
              "alle"=c(1,2,1,2),
              "X1"=c('1000','0000','1000','0000'),
              "X2"=c('0000','1000','0000','1000'),
              "X3"=c('0900','0100','9999','9999'))

который дает

      name marker alle   X1   X2   X3
1:  11-a>b      1    1 1000 0000 0900
2: 11--a>b      1    2 0000 1000 0100
3:  12-c>d      2    1 1000 0000 9999
4: 12--c>d      2    2 0000 1000 9999

Продолжение кода

#marker metadata in xmd
xmd<-x[,c(1:3)]

#data in xd.r
xd.r<-x[,c(4:ncol(x)),with=FALSE]

#select metadata where column 'alle'==1
xmd.1r<-xmd[alle %in% c(1)]


#Start cluster to do the concatenation of rows
library(parallel)
library(doSNOW)
library(foreach)

#Parallel backend
cl<-makeCluster(detectCores()-1)
registerDoSNOW(cl)

#Empty matrix to fill with the result of the foreach loop
xd.r.1r<-matrix(nrow=(nrow(xd.r)/2),
          ncol=ncol(xd.r))

#concatenation of contiguous rows via foreach
xd.r.1r<-foreach(i=Map(c,
                       c(1:nrow(xd.r))[c(T,F)], #odd row indexes of xd.r
                       c(1:nrow(xd.r))[c(F,T)], #even row indexes of xd.r
                       c(1:(nrow(xd.r)/2))),    #row indexes for xd.r.1r
                 .combine=rbind) %dopar% {
                   xd.r.1r[i[3],]<-paste(xd.r[i[1],              # Concatenate i[1] odd row with
                                              c(1:ncol(xd.r))],  # Next i[2] even row, with no separation
                                         xd.r[i[2],              # and fill xd.r.1r by i[3] row
                                              c(1:ncol(xd.r))],
                                         sep="")
                 }

#Turn the matrix into a data table
colnames(xd.r.1r)<-colnames(xd.r)
xd.r.1r<-as.data.table(xd.r.1r)

#Combine the metadata table where column 'alle'==1 and resulting table
xf.1r<-cbind.data.frame(xmd.1r,
                        xd.r.1r)
#Finalize the cluster
stopCluster(cl)

Фактический (и желаемый) результат

     name marker alle       X1       X2       X3
1: 11-a>b      1    1 10000000 00001000 09000100
2: 12-c>d      2    1 10000000 00001000 99999999

...