dplyr 和 mid-pipe 消息

r2e*_*ans 5 r dplyr

我偶尔会有长时间运行的管道,并且我希望message随着阶段的进展而快速运行。我想

log_midpipe <- function(x, expr) { expr; x; }
Run Code Online (Sandbox Code Playgroud)

(并且也尝试过force(expr)),但消息时间全部错误。

library(dplyr)
sleep <- function(x, time=3) { Sys.sleep(3); x; }
message(Sys.time(), " start"); 
mtcars %>%
  log_midpipe(message(Sys.time(), " hello1")) %>%
  sleep(.) %>%
  log_midpipe(message(Sys.time(), " hello2")) %>%
  sleep(.) %>%
  head(3)
message(Sys.time(), " done")
# 2021-04-16 08:51:09 start
# 2021-04-16 08:51:12 hello2
# 2021-04-16 08:51:15 hello1
# 2021-04-16 08:51:15 done
#                mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Run Code Online (Sandbox Code Playgroud)

无序是(我相信)是因为参数的评估方式:懒惰地,一旦从管道转换为嵌套的“括号式”命令堆栈,消息传递"hello1"是最外层的,这意味着它最后评估。

有没有一种简单的方法可以实时获取中段管道记录?

我希望得到

# 2021-04-16 08:51:09 start
# 2021-04-16 08:51:09 hello1
# 2021-04-16 08:51:12 hello2
# 2021-04-16 08:51:15 done
Run Code Online (Sandbox Code Playgroud)

Rob*_*ach 3

log_midpipe您可以通过强制首先评估来使它们按正确的顺序排列x

这应该适用于实际示例,其中长时间运行的代码是 in 的一部分xsleep而不是事先单独的调用,因为Sys.sleep不需要x评估任何部分。

log_midpipe <- function(x, expr) {
  result <- x
  expr 
  result
}
Run Code Online (Sandbox Code Playgroud)

sleep需要作为输入来执行其长时间运行的过程的Ax看起来像这样并以正确的间隔打印:

sleep <- function(x, time=3) { 
  result <- x
  Sys.sleep(3)
  result
}
Run Code Online (Sandbox Code Playgroud)