“Furrr”包 R:future_pmap 维数不正确;由尝试提取矩阵行引起; .l 是两个变量

问题描述 投票:0回答:1

我怀疑该错误与我不了解如何使用 future_pmap 多次运行此函数有关;正如您在下面看到的,我指定 NTrials 来证明我希望该函数在这个特定场景中运行 20 次。如果您希望通过复制代码提供帮助,请注意您正在使用的核心。

library("furrr")
library("parallel")
testmatrix<-matrix(runif((20000*11),-1,21),nrow = 20000, ncol = 11)

Testfunction<-function(ParVp,Ntrials){
  for(simnum in 1:Ntrials){
    #locate parameters for in-host dynamics
    Vp=ParVp[, 1:2]
    tp=ParVp[, 3:4]
    lg=ParVp[, 5:6]
    ld=ParVp[, 7:8]
    Tc=ParVp[, 9:10]
    rho=ParVp[, 11]
    
  print(head(Vp))
  
  }
}
ncores<-detectCores()-2
plan(multisession, workers = ncores)
Testoutput<- future_pmap(list(testmatrix,20),Testfunction)
plan(sequential)

(function (.l, .f, ..., .progress = FALSE) 中的错误: ℹ 索引:1。 由

ParVp[, 1:2]
中的错误引起: !维数不正确

r furrr
1个回答
0
投票

您通过

future_*()
进行的函数调用由单个工作人员处理,这意味着您很可能希望避免该函数中中的循环和其他迭代。

从简单开始。

furrr
基本上是
purrr
与 future,因此暂时退出并行性并首先使用
purrr
工作,选择最适合手头任务的
purrr
工具可能是有意义的。

在您的示例中,您有一个矩阵和多个试验,后者可以被视为一系列试验,这将是迭代器的输入。由于我们只需要迭代单个序列,因此这里不需要

pmap()
,只需要
map()
。由于我们(大概)希望获得每次迭代的结果,因此我们的函数也应该返回一些东西。包括 1 秒的延迟,这样我们就可以轻松测量顺序 (
purrr
) 和并行 (
furrr
) 执行之间的差异。

library(purrr)

set.seed(42)
testmatrix <- matrix(runif((20000*11), -1, 21), nrow = 20000, ncol = 11)

Testfunction <- function(trial_n, ParVp = testmatrix) {
  # let's simulate a slowish process, sleep for a ssecond
  Sys.sleep(1)
  # return something
  ParVp[, 1:2] + trial_n * 100 
}

n_trials <- 5
# measuring elapsed time
tictoc::tic("map Testfunction")
Testoutput_1 <- map(1:n_trials, Testfunction)
tictoc::toc()
#> map Testfunction: 5.13 sec elapsed

# check results 
str(Testoutput_1)
#> List of 5
#>  $ : num [1:20000, 1:2] 119 120 105 117 113 ...
#>  $ : num [1:20000, 1:2] 219 220 205 217 213 ...
#>  $ : num [1:20000, 1:2] 319 320 305 317 313 ...
#>  $ : num [1:20000, 1:2] 419 420 405 417 413 ...
#>  $ : num [1:20000, 1:2] 519 520 505 517 513 ...

在 5 秒多的时间里,我们获得了输入结果的匹配列表 (

1:n_trials
)。

是时候移动到

furrr
:

library(parallel)
library(furrr)

(ncores <- detectCores() - 2)
#> [1] 6
plan(multisession, workers = ncores)

tictoc::tic("future_map Testfunction")
Testoutput_2 <- future_map(1:n_trials, Testfunction)
tictoc::toc()
#> future_map Testfunction: 2.1 sec elapsed

str(Testoutput_2)
#> List of 5
#>  $ : num [1:20000, 1:2] 119 120 105 117 113 ...
#>  $ : num [1:20000, 1:2] 219 220 205 217 213 ...
#>  $ : num [1:20000, 1:2] 319 320 305 317 313 ...
#>  $ : num [1:20000, 1:2] 419 420 405 417 413 ...
#>  $ : num [1:20000, 1:2] 519 520 505 517 513 ...

我们在 2.1 秒内获得了 5 次函数调用的结果,每次调用需要 1 秒。


在需要迭代 data.frame 行或确实有超过 2 个列表/向量(对于 2 个有

pmap()
)的情况下,保留
furrr_map()
/
map2
,在后一种情况下,你将向其传递一个列表列表,类似这样的东西
(来自
?furrr::future_pmap
):

x <- list(1, 10, 100)
y <- list(1, 2, 3)
z <- list(5, 50, 500)

future_pmap(list(x, y, z), my_function_with_3_arguments)

如果你因为“p”像“并行”而选择

pmap
,那么这里的上下文不是“并行执行”,而是并行迭代多个向量,即每次迭代从输入列表中的每个向量中获取第n项。

© www.soinside.com 2019 - 2024. All rights reserved.