是什么触发了“祖先必须是环境”错误?

Alb*_*app 6 r dplyr doparallel

我正在运行并行计算,用于foreach同时处理大量时间序列。在这些计算中(在一个名为我的函数中,compute_slope()我做了这样的事情

\n
lBd <- floor(TMax^delta) # lower bound\nuBd <-  ceiling(m * TMax^delta) # upper bound\n    \n# process is a tibble with columns `n` and `variance`\nprocess %>% \n  dplyr::filter(between(n, lBd, uBd)) %>% \n  lm(data = ., log(variance) ~ log(n)) %>% \n  coefficients() %>% \n  .[2]\n
Run Code Online (Sandbox Code Playgroud)\n

所以,这是非常简单的事情:使用参数TMaxdeltam在左侧和右侧截断时间序列(使用filter()),然后对截断的时间序列运行线性回归。\n出于某种奇怪的原因,大多数时候一切都很顺利,但有时(我怀疑在较长的时间序列中更有可能发生错误,即TMax较大,但这也有点不规则)我得到

\n
\xe2\x9c\x96 Problem with `filter()` input `..1`.\n\xe2\x84\xb9 Input `..1` is `between(n, lBd, uBd)`.\n\xe2\x9c\x96 `ancestor` must be an environment"\n
Run Code Online (Sandbox Code Playgroud)\n

我真的不知道如何解释这个错误。我也很难复制这个“祖先”错误,但到目前为止还没有运气。例如,我尝试过

\n
lBd <- floor(TMax^delta) # lower bound\nuBd <-  ceiling(m * TMax^delta) # upper bound\n    \n# process is a tibble with columns `n` and `variance`\nprocess %>% \n  dplyr::filter(between(n, lBd, uBd)) %>% \n  lm(data = ., log(variance) ~ log(n)) %>% \n  coefficients() %>% \n  .[2]\n
Run Code Online (Sandbox Code Playgroud)\n

在每种情况下,都会创建不同的(可解释的)错误消息。我怀疑错误消息是由于并行处理过程中发生的一些奇怪的事情引起的,但我不确定那可能是什么。无论如何,我们将不胜感激这个祖先错误的例子。也许从那里我可以回到我的计算中出错的地方。

\n

更新

\n

即使在向脚本添加回溯之后,我仍然无法弄清楚并行化发生了什么。这就是它提供的

\n
Error in { : \n  task 34 failed - "Problem with `mutate()` column `grid_estimates`.\n\xe2\x84\xb9 `grid_estimates = map(data, ~estimate_var_on_grid(process = ., TMax = TMax, grid = grid))`.\n\xe2\x9c\x96 Problem with `mutate()` column `slope`.\n\xe2\x84\xb9 `slope = map2_dbl(m, delta, ~compute_slope(process, .x, .y, TMax))`.\n\xe2\x9c\x96 could not find function "::""\nCalls: compute_metrics_on_stable_splits ... tibble -> tibble_quos -> eval_tidy -> %dopar% -> <Anonymous>\n11: (function () \n    traceback(2))()\n10: stop(simpleError(msg, call = expr))\n9: e$fun(obj, substitute(ex), parent.frame(), e$data)\n8: foreach(i = itx, .packages = c("tidyverse", "yardstick", "rsample"), \n       .export = #vector of exports removed for legibility\n) %dopar% {\n       i %>% \n         pull(splits) %>% \n         .[[1]] %>% \n         train_and_test(., train_grid = grid, my_mset = my_mset, \n                   method = method, TMax = TMax_eval)\n       }\n   }\n7: eval_tidy(xs[[j]], mask)\n6: tibble_quos(xs, .rows, .name_repair)\n5: tibble(metrics = .)\n4: list2(...)\n3: bind_cols(select(splits, alpha), .)\n2: foreach(i = itx, .packages = c("tidyverse", "yardstick", "rsample"), \n       .export = #vector of exports removed for legibility\n) %dopar% {\n       i %>% \n         pull(splits) %>% \n         .[[1]] %>% \n         train_and_test(., train_grid = grid, my_mset = my_mset, \n                   method = method, TMax = TMax_eval)\n       }\n   } %>% \n     tibble(metrics = .) %>% \n     bind_cols(select(splits, alpha), .)\n1: compute_metrics_on_stable_splits(method = method, grid = grid, \n       my_mset = metric_set(accuracy, mcc, sens, spec), TMax_eval = TMax_eval, \n       v = 40)\n
Run Code Online (Sandbox Code Playgroud)\n

现在的错误could not find function "::"与祖先错误一样奇怪。其他时候我也收到过

\n
\'rho\' must be an environment not pairlist: detected in C-level eval\n
Run Code Online (Sandbox Code Playgroud)\n

显然,即使脚本中的代码保持不变,错误也可能不同。此时任何线索将不胜感激。奇怪的是,在某些情况下,完全相同的代码要么因更改错误消息而失败,要么有时完成(如果我不需要使用此脚本运行更多计算,那么我已经对得到的结果感到满意了当代码成功完成时)。

\n

会议信息

\n
R version 4.1.2 (2021-11-01)\nPlatform: x86_64-pc-linux-gnu (64-bit)\nRunning under: Red Hat Enterprise Linux 8.2 (Ootpa)\n\nMatrix products: default\nBLAS/LAPACK: /pfs/data5/software_uc2/all/toolkit/Intel_OneAPI/mkl/2021.4.0/lib/intel64/libmkl_intel_lp64.so.1\n\nlocale:\n [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C\n [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8\n [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8\n [7] LC_PAPER=en_US.UTF-8       LC_NAME=C\n [9] LC_ADDRESS=C               LC_TELEPHONE=C\n[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C\n\nattached base packages:\n[1] parallel  stats     graphics  grDevices utils     datasets  methods\n[8] base\n\nother attached packages:\n [1] yardstick_0.0.9   doParallel_1.0.16 iterators_1.0.13  foreach_1.5.1\n [5] forcats_0.5.1     stringr_1.4.0     dplyr_1.0.7       purrr_0.3.4\n [9] readr_2.1.1       tidyr_1.1.4       tibble_3.1.6      ggplot2_3.3.5\n[13] tidyverse_1.3.1\n\nloaded via a namespace (and not attached):\n [1] tidyselect_1.1.1 haven_2.4.3      colorspace_2.0-2 vctrs_0.3.8\n [5] generics_0.1.1   utf8_1.2.2       rlang_0.4.12     pillar_1.6.4\n [9] glue_1.5.1       withr_2.4.3      DBI_1.1.1        dbplyr_2.1.1\n[13] modelr_0.1.8     readxl_1.3.1     lifecycle_1.0.1  plyr_1.8.6\n[17] munsell_0.5.0    gtable_0.3.0     cellranger_1.1.0 rvest_1.0.2\n[21] codetools_0.2-18 tzdb_0.2.0       fansi_0.5.0      broom_0.7.10\n[25] Rcpp_1.0.7       scales_1.1.1     backports_1.4.0  jsonlite_1.7.2\n[29] fs_1.5.1         hms_1.1.1        stringi_1.7.6    grid_4.1.2\n[33] cli_3.1.0        tools_4.1.2      magrittr_2.0.1   crayon_1.4.2\n[37] pkgconfig_2.0.3  ellipsis_0.3.2   xml2_1.3.3       pROC_1.18.0\n[41] reprex_2.0.1     lubridate_1.8.0  assertthat_0.2.1 httr_1.4.2\n[45] rstudioapi_0.13  R6_2.5.1         compiler_4.1.2\n
Run Code Online (Sandbox Code Playgroud)\n

Alb*_*app 1

我真的不确定这是否是一个明确的答案,以及问题是否可能随时再次发生,但现在我相信问题来自于使用foreach. 这可能不是特定于该foreach包的,而是竞争条件的结果,我怀疑它也是一个Heisenbug

话虽这么说,最有帮助的是确保当其中一个工作人员出现某种错误时 foreach 循环不会终止。更准确地说,我已将.errorhandling- 参数设置为"pass"。为了使循环发生错误,只需将该迭代的错误消息写入列表中,并将其他结果也收集在同一列表中。

原则上,代码如下所示

results <- foreach (
  i = itx, # itx is an iterator created via iter()
  .errorhandling = 'pass',
  .packages = #packages,
  .export = #exports
) %dopar% {
  # Code for parallel computation here
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,一旦我添加了错误处理选项,就不再发生错误,并且我可以连续多次运行该脚本而不会出现任何问题。因此,我相信我们这里有一个 Heisenbug。