Подтвердить что ты не робот

Непоследовательные результаты для f (g (x)) вместе или расщепления

Во время недавнего расследования в установление случайных семян внутри функций я столкнулся с нечетной ситуацией. Рассмотрим функции f и g, каждый из которых устанавливает случайное семя, а затем выполняет простую рандомизированную операцию:

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

Поскольку каждая функция устанавливает случайное семя, я бы ожидал, что каждая функция всегда будет иметь одинаковое возвращаемое значение, учитывая тот же ввод. Это означает, что f(g(2)) должен возвращать то же самое, что и x <- g(2) ; f(x). К моему удивлению, это не так:

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

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

Что здесь происходит?

4b9b3361

Ответ 1

Это пример эксперимента с двойным разрезом 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

Ответ 2

Аргумент x вашей функции f() оценивается только в тот момент, когда он фактически используется внутри функции. Это означает, что set.seed(2) оценивается перед выполнение функции g() при попытке вычислить f(g(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