f(g(x))结果不一致或分裂的结果不一致

在最近一项关于在function中设置随机种子的调查中 ,我遇到了一个奇怪的情况。 考虑函数fg ,每个函数设置随机种子,然后执行一个简单的随机操作:

 g <- function(size) { set.seed(1) ; runif(size) } f <- function(x) { set.seed(2) ; x*runif(length(x)) } 

因为每个函数设置随机种子,我希望每个函数总是具有相同的返回值给定相同的input。 这意味着f(g(2))应该返回与x <- g(2) ; f(x) x <- g(2) ; f(x) 。 令我惊讶的是,情况并非如此:

 f(g(2)) # [1] 0.1520975 0.3379658 x <- g(2) f(x) # [1] 0.04908784 0.26137017 

这里发生了什么?

这是双缝R实验的一个例子。 当观察到x时,它就像一个粒子; 当不可见的时候,它就像波浪一样。 看哪

 g <- function(size) { set.seed(1) ; runif(size) } f <- function(x) {set.seed(2) ; x*runif(length(x)) } f2 <- function(x) {print(x); set.seed(2) ; x*runif(length(x)) } f(g(2)) # [1] 0.1520975 0.3379658 x <- g(2) f(x) # [1] 0.04908784 0.26137017 f2(g(2)) # [1] 0.2655087 0.3721239 # [1] 0.04908784 0.26137017 x <- g(2) f2(x) # [1] 0.2655087 0.3721239 # [1] 0.04908784 0.26137017 

我只是在笑你。 print是强制x 。 你可以明确地做到这一点

 f <- function(x) {force(x); set.seed(2) ; x*runif(length(x)) } x <- g(2) f(x) # [1] 0.04908784 0.26137017 

但不是这个

 f(force(g(2))) # [1] 0.1520975 0.3379658 

f()函数的x参数只在函数内部实际使用的时候才被计算。 这意味着在尝试计算f(g(2))在执行g()函数之前set.seed(2)进行求值。

 > f(g(2)) [1] 0.1520975 0.3379658 

基本上相当于:

 > set.seed(2) > set.seed(1) > result <- runif(2) > result*runif(length(result)) [1] 0.1520975 0.3379658