2017-09-07 23 views
1

經過前面的討論和F.Privé的幫助,我做了一些更改,下面的代碼實際上正在做預期的工作。並行包的並行化方法似乎返回一個空列表

library(purrr) 
library(parallel) 

p_list = list("P1" = list(c("MAKM1","MMERMTD","FTRWDSE")) , 
        "P2" = list(c("MFFGGDSF1","DFRMDFMMGRSDFG","DSDMFFF")), 
        "P3" = list(c("MDERTDF1","DFRGRSDFMMG","DMMMFFFS")), 
        "P4" = list(c("MERTSDMDF1","SDFRGSSMRSDFG","DFFFM"))) 


chars <- set_names(c("M", "S", "M"), c("class.1", "class.35", "class.4")) 

get_0_and_all_combn <- function(x) { 
    map(seq_along(x), function(i) combn(as.list(x), i, simplify = FALSE)) %>% 
    unlist(recursive = FALSE) %>% 
    c(0L, .) 
} 


get_pos_combn <- function(x, chars) { 
    x.spl <- strsplit(x, "")[[1]] 

    isUni1 = grep("class.1", names(chars)) 
    isFirst = grepl("1",x) 

    map2(.x=chars, .y=seq_along(chars), .f=function(chr, index) { 

    if(length(isUni1) != 0){ 
     if(index == isUni1 & isFirst == TRUE) 
     1 %>% get_0_and_all_combn() 
     else{ 
     which(x.spl == chr) %>% 
      get_0_and_all_combn() 
     } 
    }else{ 
     which(x.spl == chr) %>% 
     get_0_and_all_combn() 
    } 

    }) %>% 
    expand.grid() 
} 


get_pos_combn_with_infos <- function(seq, chars, p_name) { 
    cbind.data.frame(p_name, seq, get_pos_combn(seq, chars)) 
} 

combine_all <- function(p_list, chars){ 

    i = 1 
    fp <- as.data.frame(matrix(ncol = 5)) 
    colnames(fp) = c("p_name" ,"seq" , names(chars)) 

    for(p in p_list){ 

    p_name = names(p_list)[i] 

    for(d in 1:length(p[[1]])){ 

     seq = p[[1]][d] 

     f = get_pos_combn_with_infos(seq, chars, p_name) 
     # unlist the list wherever exist in the dataframe and collapse 
     # its values with the ":" symbol. 
     for(c in 1:nrow(f)){ 
     if(is.list(f[c,3])) 
      f[c,3]=paste(unlist(f[c,3]),collapse=":") 
     if(is.list(f[c,4])) 
      f[c,4]=paste(unlist(f[c,4]),collapse=":") 
     if(is.list(f[c,5])) 
      f[c,5]=paste(unlist(f[c,5]),collapse=":") 
     } 

     fp = na.omit(rbind(f , fp)) 
    } 

    i = i + 1 
    } 

    fp 
} 


numCores <- detectCores() 

results = mcmapply(FUN=combine_all, MoreArgs=list(p_list , chars) , mc.cores = numCores-1) 

,應該運行的唯一的事情是最後一個函數(combine_all()),給作爲輸入p_listchars變量。

如果這樣做,其結果是包含在chars可變

定義的字符的字符串(p_list)內的位置的所有可能組合的所有可能組合的data.frame我知道這是一個有點有點複雜,但我不知道另一種解釋結果的方式。

無論如何。因爲我的實際列表(p_list)比上面示例中的更大,我認爲它一次在多個CPU內核上並行運行。

爲此,您可以看到我使用了parallel包。我運行它在一個Linux的盒子(因爲據我所知mcmapply使用fork來創建其他進程),但事實是,我沒有得到任何結果,除了一個空的列表。

任何想法或許可以改進算法或使其並行運行是值得歡迎的。

謝謝。

回答

2

在這裏,問題是你如何使用mapply。如果您沒有提供任何向量化參數(...),則返回長度爲0的列表是正常的。

我將使用foreach,因爲它更易於使用。你可以看到this guide for parallelism in R with foreach

然後combine_all成爲

combine_all <- function(p_list, chars) { 

    p_names <- names(p_list) 

    all_all_f <- foreach(i = seq_along(p_list)) %dopar% { 

    p <- p_list[[i]][[1]] 
    p_name <- p_names[i] 

    all_f <- foreach(d = seq_along(p)) %do% { 

     f <- get_pos_combn_with_infos(p[d], chars, p_name) 
     # unlist the list wherever exist in the dataframe and collapse 
     # its values with the ":" symbol. 
     for(c in 1:nrow(f)){ 
     if(is.list(f[c,3])) 
      f[c,3]=paste(unlist(f[c,3]),collapse=":") 
     if(is.list(f[c,4])) 
      f[c,4]=paste(unlist(f[c,4]),collapse=":") 
     if(is.list(f[c,5])) 
      f[c,5]=paste(unlist(f[c,5]),collapse=":") 
     } 

     f 
    } 

    do.call("rbind", all_f) 
    } 

    do.call("rbind", all_all_f) 
} 

然後你做

library(foreach) 
doParallel::registerDoParallel(parallel::detectCores() - 1) 
the_res_you_want <- combine_all(p_list = p_list, chars = chars) 
doParallel::stopImplicitCluster() 

在Linux和Mac,這是註冊叉集羣(MC-等)。在Windows上,這段代碼很可能不起作用。

PS1:請注意,如果您對多個元素進行並行處理,那麼您的數據框可能非常大。

PS2:你應該真的保留數據框與列列表,而不是摺疊成字符串。見http://r4ds.had.co.nz/many-models.html#list-columns-1

+0

要在Linux/macOS上模擬Windows行爲,請使用'doParallel :: registerDoParallel(cl < - parallel :: makeCluster(2L))'。事實上,它扼殺了缺失的對象(「全局」)。 – HenrikB

+0

但是,使用[doFuture](https://cran.r-project.org/package=doFuture)後端的東西在所有平臺(Linux,macOS和Windows)以及所有後端(不只是分叉那些)。所以,在上面的Florian的例子中嘗試以下方法,它將起作用:'library(「doFuture」); registerDoFuture();計劃(多處理)'。對於其他類型的並行後端,請參閱https://cran.r-project.org/package=future的主要插圖 – HenrikB

相關問題