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)
유일한 것은 p_list
및 chars
변수를 입력으로주고, 마지막 기능 (combine_all()
)입니다. 이 작업이 완료되면
, 결과는 내가 조금의 알고 chars
변수
에 정의 된 문자의 문자열 (p_list
) 내부에 위치의 모든 가능한 조합의 가능한 모든 조합을 포함하는 data.frame입니다 조금 복잡하지만 결과를 설명하는 다른 방법을 모른다.
어쨌든. 필자의 실제 목록 (p_list)이 위 예제의 것보다 충분히 크기 때문에 한 번에 둘 이상의 CPU 코어에서 병렬 모드로 실행하도록 생각했습니다.
내가 볼 수 있듯이 parallel
패키지를 사용했습니다. 나는 리눅스 박스에서 실행한다. 왜냐하면 mcmapply
이 다른 프로세스를 생성하기 위해 fork를 사용한다는 것을 이해했기 때문이다. 그러나 진실은 빈리스트를 제외하고는 아무 결과도 없다는 것이다.
알고리즘을 개선하거나 병렬로 실행하는 것이 좋습니다.
감사합니다.
Linux/macOS에서 Windows 동작을 에뮬레이트하려면'doParallel :: registerDoParallel (cl <- parallel :: makeCluster (2L))'을 사용하십시오. 실제로, 누락 된 객체 ("전역")에 질식합니다. – HenrikB
그러나 [doFuture] (https://cran.r-project.org/package=doFuture) 백엔드를 사용하면 모든 플랫폼 (Linux, macOS 및 Windows) 및 모든 백엔드에서 동일한 작업을 수행 할 수 있습니다. 1). 그래서, 위의 플로리안의 예제를 사용하여 다음을 시도해보십시오 :'library ("doFuture"); registerDoFuture(); 계획 (다중 프로세스)'. 다른 유형의 병렬 백엔드의 경우 https://cran.r-project.org/package=future의 기본 비 네트를 참조하십시오. – HenrikB