Dataframe 使用mclappy并行化R代码不会生成正确的结果

Dataframe 使用mclappy并行化R代码不会生成正确的结果,dataframe,sapply,r,parallel-processing,data-manipulation,mclapply,Dataframe,Sapply,R,Parallel Processing,Data Manipulation,Mclapply,我有一个df,需要应用一个函数给每列打分(calc.fitness): 使用,我将得到以下结果,这是正确的结果,但随着df大小的增加,这将非常耗时: sapply(as.list(df), calc.fitness,filterTable=my.df) # ch1 ch2 ch3 ch4 ch5 ch6 ch7 ch8 # 8.4813

我有一个
df
,需要应用一个函数给每列打分(
calc.fitness
):

使用,我将得到以下结果,这是正确的结果,但随着
df
大小的增加,这将非常耗时:

sapply(as.list(df), calc.fitness,filterTable=my.df)
#     ch1          ch2            ch3            ch4            ch5            ch6            ch7             ch8 
# 8.481359e-02  6.419552e-01   5.847587e-02   6.713477e-02   1.552056e-01   1.305787e+34   2.805074e-01    2.039931e+00 
我使用[Tag:mclappy`使其更快,如下所示:

numCores <- detectCores()
result <- unlist(mclapply(1:8, function(x) {
  return(calc.fitness(df[,x], filterTable=my.df))}, mc.preschedule = TRUE, mc.cores = numCores))

# result
# [1] 8.481359e-02 8.481359e-02 8.481359e-02 8.481359e-02 1.305787e+34 1.305787e+34 1.305787e+34 1.305787e+34
my.df:


感谢您的帮助。

< P>代码> SpIs<代码>简化为一个矩阵,同时列出列的列返回每个列的向量,一个接一个。考虑使用<代码> CubSoS//Cuff>函数作为说明:

df ch1 ch2 ch3 ch4 ch5 ch6 ch7 ch8
#>  [1,]   5   2   7  10   7  10  10   6
#>  [2,]   6   6  12  14   8  12  15  10
#>  [3,]  22  20  19  18  10  14  23  17
#>  [4,]  29  25  24  21  12  19  24  23
#>  [5,]  36  27  25  24  19  21  28  24
#>  [6,]  40  34  36  28  28  24  37  38
#>  [7,]  52  42  42  35  33  33  44  42
#>  [8,]  56  44  45  37  35  37  45  43
#>  [9,]  57  46  46  38  37  38  47  44
unlist(并行::mclappy(1:8,函数(x){
返回值(总和(df[,x])},mc.preschedule=TRUE,mc.cores=4L)
#>  [1]  5  6 22 29 36 40 52 56 57  2  6 20 25 27 34 42 44 46  7 12 19 24 25 36 42
#> [26] 45 46 10 14 18 21 24 28 35 37 38  7  8 10 12 19 28 33 35 37 10 12 14 19 21
#> [51] 24 33 37 38 10 15 23 24 28 37 44 45 47  6 10 17 23 24 38 42 43 44
调用(cbind,parallel::mclappy)(1:8,函数(x){
返回值(总和(df[,x])},mc.preschedule=TRUE,mc.cores=4L)
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#>  [1,]    5    2    7   10    7   10   10    6
#>  [2,]    6    6   12   14    8   12   15   10
#>  [3,]   22   20   19   18   10   14   23   17
#>  [4,]   29   25   24   21   12   19   24   23
#>  [5,]   36   27   25   24   19   21   28   24
#>  [6,]   40   34   36   28   28   24   37   38
#>  [7,]   52   42   42   35   33   33   44   42
#>  [8,]   56   44   45   37   35   37   45   43
#>  [9,]   57   4618   46   38   37   38   47   44
由(v0.3.0)于2020年3月25日创建

编辑:
查看功能后,您将在其中生成的数据附加到一个文件中。如果按顺序执行,这可能会很好,但在并行进程中执行此操作时,您肯定会遇到麻烦。单独并行生成多个葡萄酒进程也可能不是最有效的开始步骤,即使它生成了正确的results(使用
profvis
软件包分析(线性)代码将显示瓶颈)。除了
2017File.exe
计算
fitness.val
之外,还有其他方法吗


如果您的计划确实是按顺序从列中追加结果,那么为了正确地启动exe文件并行生成结果,您可能必须保存顺序增长文件的唯一实例(write.fwf命令)然后将这些文件与exe命令并行传递,为每个连续步骤生成唯一的output.txt文件,然后按照正确的顺序加载结果。

Hi Nikki,如果您提供函数
calc.fitness
或它来自的包的代码,将更容易提供帮助。Hi Ian,calc.fitness是一个长函数我写过,我试着让它简短易懂!我编辑了这篇文章,你可以看到它的功能!提前非常感谢!在看到你的功能后,你将在其中生成的数据附加到一个文件中。如果按顺序进行,这可能会很好,但如果你在并行过程中这样做,你肯定会遇到麻烦。请参阅我的编辑编辑评论。
numCores <- detectCores()
result <- unlist(mclapply(1:8, function(x) {
  return(calc.fitness(df[,x], filterTable=my.df))}, mc.preschedule = TRUE, mc.cores = numCores))

# result
# [1] 8.481359e-02 8.481359e-02 8.481359e-02 8.481359e-02 1.305787e+34 1.305787e+34 1.305787e+34 1.305787e+34
calc.fitness <- function(df.val, filterTable = my.df) {
  input.path <- "/home/Nikki/Desktop/v2017.0/exec/Input_2017.txt"
  filterTable$xe <-  df.val[1]
  filterTable$xth <- df.val[2]
  filterTable$xfi <- df.val[3]
  filterTable$xfw <- df.val[4]
  filterTable$xfm <- df.val[5]
  filterTable$xls <- df.val[6]
  filterTable$xhls <- df.val[7]
  filterTable$xvt <- df.val[8]
  filterTable$xvd <- df.val[9]
  write.fwf(filterTable,append = TRUE,file = paste("Input_2017", ".txt", sep = ""),width = 25, rownames = F,colnames = F,quote = F)
  command <- "wine  /home/Nikki/Desktop/v2017.0/exec/2017File.exe"
  system(command)
  output.file <-read.table("/home/Nikki/Desktop/v2017.0/exec/Output_2017.txt",header = TRUE,fill = TRUE)
  output.pgt <- as.numeric(levels(output.file$pgt))[output.file$pgt]
  calc.sol <- output.pgt[!is.na(output.pgt)]
  opt.sol <- filterTable$PressureDropGL
  n <- length(calc.sol)
  subtract.val <- calc.sol - opt.sol
  denominator <- opt.sol
  sq.output <-  (subtract.val / denominator) ^ 2
  fitness.val <- sum(sq.output) / n
  return(fitness.val)
}# end of function