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)
唯一、1は実行する必要がありp_list
とchars
変数を入力として与え、最後の関数(combine_all()
)です。これが行われた場合
、結果はchars
変数
で定義された文字の文字列内の位置のすべての可能な組み合わせのすべての可能な組み合わせが含まれていdata.frame(p_list
)である私はそれを少し知っています私は結果を説明する別の方法を知らない。
とにかく。私の実際のリスト(p_list)は上記の例よりも十分に大きいので、一度に複数のCPUコアで並列モードで動作させることを考えました。
このような目的のために、私はparallel
パッケージを使用しました。私はLinuxのボックスで実行します(なぜなら、mcmapply
が他のプロセスを作成するためにforkを使うことを理解していたからです)。しかし、真実は空のリストを除いて何の結果も得られなかったことです。
多分アルゴリズムを改善したり、それを並行して実行させることをお勧めします。
ありがとうございます。
Linux/macOSでWindowsの動作をエミュレートするには、 'doParallel :: registerDoParallel(cl < - parallel :: makeCluster(2L))'を使用します。実際には、欠けているオブジェクト(「グローバル」)で窒息します。 – HenrikB
しかし、[doFuture](https://cran.r-project.org/package=doFuture)バックエンドを使うと、すべてのプラットフォーム(Linux、macOS、Windows)とすべてのバックエンドもの)。だから、上記のFlorianの例で次のように試してみましょう。これはうまくいくでしょう: 'library(" doFuture "); registerDoFuture();計画(マルチプロセス) '。他のタイプの並列バックエンドについては、https://cran.r-project.org/package=futureのメインのバイナリを参照してください。 – HenrikB