管道传输时在函数内控制台的消息顺序
Order of messages to console within functions when piped
编辑:我不是有意无礼,所以只是没有接受我的问候..
您好,
为了跟踪某些函数的处理,我想在函数启动和完成时在控制台中打印消息。
我是 tidyverse
和管道操作员 %>%
的忠实粉丝。但是我刚刚发现函数开头的消息打印顺序错误,而结尾的消息顺序正确。
有人知道为什么或如何解决这个问题吗?
这是一些代码:
library(tidyverse)
testdata <- data.frame(a=c(3,5,7,1,2),b=c(2,5,6,3,9))
foo_1 <- function(DF){
message("Hello 1")
Obj <- DF %>%
mutate(Test_1=a*b)
message("Bye 1")
return(Obj)
}
foo_2 <- function(DF){
message("Hello 2")
Obj <- DF %>%
mutate(Test_2=Test_1*2)
message("Bye 2")
return(Obj)
}
foo_3 <- function(DF){
message("Hello 3")
Obj <- DF %>%
mutate(Test_3=Test_2/a)
message("Bye 3")
return(Obj)
}
testdata %>%
foo_1() %>%
foo_2() %>%
foo_3()
控制台打印的结果是:
Hello 3
Hello 2
Hello 1
Bye 1
Bye 2
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
我希望消息的顺序如下:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
您将消息从各个函数中移出,并在放置消息的地方围绕它们生成一个包装器:
使用一些类似 sudo 的代码:
my_wrapper <- function(){
message('h1')
foo_1()
message('b1')
message('h2')
...
message('b3')
}
1) flush.console 使用 flush.console 强制显示此时排队的消息。
testdata %>%
foo_1() %>%
{ flush.console(); foo_2(.) } %>%
{ flush.console(); foo_3(.) }
给出此输出:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
2) Bizarro pipe 另一种方法是使用 Bizarro pipe,这是一种巧妙的基本语法,看起来像管道。
testdata ->.;
foo_1(.) ->.;
foo_2(.) ->.;
foo_3(.)
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
3) force 强制计算三个函数中的参数。
foo_1 <- function(DF){
force(DF) #######
message("Hello 1")
Obj <- DF %>%
mutate(Test_1=a*b)
message("Bye 1")
return(Obj)
}
foo_2 <- function(DF){
force(DF) #######
message("Hello 2")
Obj <- DF %>%
mutate(Test_2=Test_1*2)
message("Bye 2")
return(Obj)
}
foo_3 <- function(DF){
force(DF) #######
message("Hello 3")
Obj <- DF %>%
mutate(Test_3=Test_2/a)
message("Bye 3")
return(Obj)
}
testdata %>%
foo_1 %>%
foo_2 %>%
foo_3
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
4) pipe_eager_lexical magrittr 开发者 Lionel 向我指出 magrittr 有一个 eager pipe 但没有将它分配给 %..% 运算符;但是,我们可以轻松做到这一点。
library(magrittr)
`%>e%` <- pipe_eager_lexical # eager pipe
testdata %>e%
foo_1() %>e%
foo_2() %>e%
foo_3()
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
编辑:我不是有意无礼,所以只是没有接受我的问候..
您好,
为了跟踪某些函数的处理,我想在函数启动和完成时在控制台中打印消息。
我是 tidyverse
和管道操作员 %>%
的忠实粉丝。但是我刚刚发现函数开头的消息打印顺序错误,而结尾的消息顺序正确。
有人知道为什么或如何解决这个问题吗?
这是一些代码:
library(tidyverse)
testdata <- data.frame(a=c(3,5,7,1,2),b=c(2,5,6,3,9))
foo_1 <- function(DF){
message("Hello 1")
Obj <- DF %>%
mutate(Test_1=a*b)
message("Bye 1")
return(Obj)
}
foo_2 <- function(DF){
message("Hello 2")
Obj <- DF %>%
mutate(Test_2=Test_1*2)
message("Bye 2")
return(Obj)
}
foo_3 <- function(DF){
message("Hello 3")
Obj <- DF %>%
mutate(Test_3=Test_2/a)
message("Bye 3")
return(Obj)
}
testdata %>%
foo_1() %>%
foo_2() %>%
foo_3()
控制台打印的结果是:
Hello 3
Hello 2
Hello 1
Bye 1
Bye 2
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
我希望消息的顺序如下:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
您将消息从各个函数中移出,并在放置消息的地方围绕它们生成一个包装器:
使用一些类似 sudo 的代码:
my_wrapper <- function(){
message('h1')
foo_1()
message('b1')
message('h2')
...
message('b3')
}
1) flush.console 使用 flush.console 强制显示此时排队的消息。
testdata %>%
foo_1() %>%
{ flush.console(); foo_2(.) } %>%
{ flush.console(); foo_3(.) }
给出此输出:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
2) Bizarro pipe 另一种方法是使用 Bizarro pipe,这是一种巧妙的基本语法,看起来像管道。
testdata ->.;
foo_1(.) ->.;
foo_2(.) ->.;
foo_3(.)
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
3) force 强制计算三个函数中的参数。
foo_1 <- function(DF){
force(DF) #######
message("Hello 1")
Obj <- DF %>%
mutate(Test_1=a*b)
message("Bye 1")
return(Obj)
}
foo_2 <- function(DF){
force(DF) #######
message("Hello 2")
Obj <- DF %>%
mutate(Test_2=Test_1*2)
message("Bye 2")
return(Obj)
}
foo_3 <- function(DF){
force(DF) #######
message("Hello 3")
Obj <- DF %>%
mutate(Test_3=Test_2/a)
message("Bye 3")
return(Obj)
}
testdata %>%
foo_1 %>%
foo_2 %>%
foo_3
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18
4) pipe_eager_lexical magrittr 开发者 Lionel 向我指出 magrittr 有一个 eager pipe 但没有将它分配给 %..% 运算符;但是,我们可以轻松做到这一点。
library(magrittr)
`%>e%` <- pipe_eager_lexical # eager pipe
testdata %>e%
foo_1() %>e%
foo_2() %>e%
foo_3()
给予:
Hello 1
Bye 1
Hello 2
Bye 2
Hello 3
Bye 3
a b Test_1 Test_2 Test_3
1 3 2 6 12 4
2 5 5 25 50 10
3 7 6 42 84 12
4 1 3 3 6 6
5 2 9 18 36 18