2015-06-27 4 views
35

Während a recent investigation in zufällige Seeds innerhalb Funktionen zu setzen, stieß ich auf eine seltsame Situation. Betrachten Funktionen f und g, von denen jeder setzt den Zufallskeim und führt dann eine einfache randomisierte Operation:Inkonsistente Ergebnisse für f (g (x)) zusammen oder aufgeteilt

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

Da jede Funktion, um die Zufallsstart setzt, würde ich jede Funktion erwarten immer haben die gleichen Rückgabewert angesichts der gleicher Eingang Dies würde bedeuten, f(g(2)) sollte das gleiche wie x <- g(2) ; f(x) zurückgeben. Zu meiner Überraschung ist das nicht der Fall:

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

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

Was ist hier los?

Antwort

37

Dies ist ein Beispiel für das Doppelspalt-R-Experiment. Wenn x beobachtet wird, wirkt es als ein Teilchen; wenn es unbeobachtet ist, wirkt es wie eine Welle. Siehe

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 

Ich bin nur josilbering Sie. print zwingt x. Sie können das tun explizit

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

Aber nicht diese

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

LOL. Das Doppelspalt-Experiment in R! Faule Bewertung als QM. Perfekt. –

+1

Schöne Verwendung von 'Josliber' als Verb. –

+0

@JosephWood Ich denke, dass all die Upvotes dafür waren – rawr

23

Das x Argument Ihrer f() Funktion nur zur Zeit ausgewertet wird, dass es tatsächlich innerhalb der Funktion verwendet wird. Das bedeutet, dass die set.seed(2)vor die Ausführung der g()-Funktion ausgewertet wird, wenn Sie versuchen, f(g(2)) zu berechnen.

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

ist im Grunde äquivalent zu:

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