在 R 中与循环并行

do parallel in R with loops

我有一个 table 集群(不止一列):

head(cluster[,c('cuil_direccion')])
[1] "PJE INDEA 98 5                    "
[2] "PJE INDE 98 5                    "
[3] "B 34 VIV RECRE 57 00                 "
[4] "S CASA DE GO 600                  "
[5] "RCCA 958 00 o                             "
[6] "JUAN B  1900                       "

我需要 运行 一个函数,为每一行提取数字并将它们粘贴到列表中。我正在使用:str_extract_all。由于 table 很大,我想拆分数据并为每个拆分使用不同的核心。我试过了:

library(foreach)
library(doParallel)
registerDoParallel(cores=detectCores(all.tests=TRUE))

crea_tabla <- function(x){
  xlst <- split(x, 1:nrow(x)) 
  pred <- foreach(i = xlst, .combine = rbind) %dopar% {
    library(stringr)
    d<-data.frame(dir='a', E_numdir=1)
    j=1  
    DIR<-i$cuil_direccion[j]
    E_NUMDIR <- str_extract_all(DIR,"\(?[0-9]+\)?")[[1]]
    d<-rbind(d, data.frame( dir=DIR , 
                         E_numdir=toString(E_NUMDIR)))
    j=1+j    
  }
}

那我运行

crea_tabla(cluster)

我得到一个空结果。

我不确定 doparallel 使用数据的方式。 E.G这部分:

 library(stringr)
    d<-data.frame(dir='a', E_numdir=1)
    j=1  

我应该写在 %dopar% 之前还是之后?

版本

num_cores<-detectCores(all.tests=TRUE)
registerDoParallel(cores=detectCores(all.tests=TRUE))



crea_tabla <- function(x, num_cores){
  xlst <- split(x, 1:nrow(x)) 
  j=1 
  d<-data.frame(dir='a', E_numdir=1) 
  pred <- foreach(i = seq_along(xlst), .combine = rbind) %dopar% {
  print(i*num_cores/nrow(x))
    library(stringr)
    DIR<-xlst[[i]]$cuil_direccion
    E_NUMDIR <- str_extract_all(DIR,"\(?[0-9]+\)?")[[1]]
    data.frame(dir=DIR , E_numdir=toString(E_NUMDIR))    
  }
  d <- rbind(d, pred)
  return(d)
}

a<-crea_tabla(cluster, num_cores)

有几点需要注意。首先,您对放置初始化变量的位置持怀疑态度是正确的。您应该在循环之前声明它们(多次重新加载库没有意义)。其次,您不需要 j 变量。只需 seq_along 您的列表并为您的列表编制索引。

接下来,关于 foreach,您已指定输出将是 rbind,因此您无需在循环内调用 rbind。如果您想要第一行,您只需将 foreach 循环的结果 rbind 到初始 data.frame。以下完成您正在尝试做的事情。

最后,我假设您已经意识到这一点,但请确保您设置了后端。我不知道您使用的是哪个 OS,但您需要使用其他软件包,例如 doParalleldoMCdoSNOW.

# recreate your data
cluster <- read.table(header=F, text='
"PJE INDEA 98 5                    "
"PJE INDE 98 5                    "
"B 34 VIV RECRE 57 00                 "
"S CASA DE GO 600                  "
"RCCA 958 00 o                             "
"JUAN B  1900                       "
')
colnames(cluster) <- 'cuil_direccion'

library(stringr)
library(foreach)

crea_tabla <- function(x){
    xlst <- split(x, 1:nrow(x)) 
    j=1 
    d<-data.frame(dir='a', E_numdir=1) 
    pred <- foreach(i = seq_along(xlst), .combine = rbind) %dopar% {
        DIR<-xlst[[i]]$cuil_direccion
        E_NUMDIR <- str_extract_all(DIR,"\(?[0-9]+\)?")[[1]]
        data.frame(dir=DIR , E_numdir=toString(E_NUMDIR))    
    }
    d <- rbind(d, pred)
    return(d)
}

crea_tabla(cluster)

                                         dir   E_numdir
1                                          a          1
2         PJE INDEA 98 5                          98, 5
3          PJE INDE 98 5                          98, 5
4      B 34 VIV RECRE 57 00                  34, 57, 00
5         S CASA DE GO 600                          600
6 RCCA 958 00 o                                 958, 00
7        JUAN B  1900                              1900