我偶尔会有长时间运行的管道,并且我希望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)
log_midpipe您可以通过强制首先评估来使它们按正确的顺序排列x。
这应该适用于实际示例,其中长时间运行的代码是 in 的一部分x,sleep而不是事先单独的调用,因为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)