2013-10-08 18 views
5

Ich versuche, die bnlearnpackage zu verwenden, bedingte Wahrscheinlichkeiten zu berechnen, und ich bin in ein Problem, wenn die "cpquery" Funktion innerhalb einer Schleife verwendet wird. Ich habe ein Beispiel erstellt, das unten gezeigt wird, das Daten verwendet, die mit dem Paket enthalten werden. Bei Verwendung der Funktion cpquery in einer Schleife wird eine in der Schleife erstellte Variable (im Beispiel "evi") von der Funktion nicht erkannt. Ich erhalte den Fehler:Verwendung von bnlearn Funktion "cpquery" innerhalb einer Schleife

Error in parse(text = evi) : object 'evi' not found 

Die Erstellungsschritte von "evi" basieren auf Beispielen, die vom Autor zur Verfügung gestellt werden.

Jede Hilfe, die Sie zur Verfügung stellen könnten, wäre großartig. Ich bin verzweifelt, einen Weg zu finden, dass ich die cpquery-Funktion für eine große Anzahl von Beobachtungen anwenden kann.

library(bnlearn) 
data(learning.test) 
fitted = bn.fit(hc(learning.test), learning.test) 

bn.function <- function(network, evidence_data) { 
    a <- NULL 
    b <- nrow(evidence_data) 
    for (i in 1:b) { 
    evi <- paste("(", names(evidence_data), "=='", 
       sapply(evidence_data[i,], as.character), "')", 
       sep = "", collapse = " & ") 
    a[i] <- cpquery(network, (C=='c'), eval(parse(text=evi))) 
    } 
    return(a) 
} 

test <- bn.function(fitted, learning.test) 

Vielen Dank im Voraus!

+1

Ich hatte Kontakt mit dem Autor des Pakets bnlearn, und es scheint, dass der Fehler, den ich erhalte, auf ein Problem mit der Funktion cpquery zurückzuführen ist. Dies ist offensichtlich, wenn ich in der Lage bin, die Funktion cpquery ordnungsgemäß in einer For-Schleife zu verarbeiten, die außerhalb einer benutzerdefinierten Funktion erstellt wird, aber den Fehler aufweist, wenn dieselbe For-Schleife _inside_ eines benutzerdefinierten verwendet wird Funktion. –

Antwort

0

das Scoping-Problem zu vermeiden, können Sie den Anruf eval und tun verschieben es innerhalb die cpquery Funktion. Wenn Sie evi (die Zeichenvariable) direkt an cpquery übergeben und dann in der Definition analysieren, erhält die Kette der Umgebungen shifted und cpquery Zugriff auf evi.

können Sie m.cpquery <- edit(cpqurey) benutzen, um Ihre eigene Version der Funktion gabeln und die folgende Zeile am Anfang einfügen:

evidence = parse(text = evidence) 

und dann neue Funktion speichern. So die Überschrift von m.cpquery wird wie folgt aussehen:

> m.cpquery 
function (fitted, event, evidence, cluster = NULL, method = "ls", 
    ..., debug = FALSE) 
{ 
    evidence = parse(text = evidence) 
    check.fit(fitted) 
    check.logical(debug) 
... 

Jetzt können Sie m.cpquery in eine eigene Funktion wie vor verwenden, es sei denn wir die Ebene Zeichenvariable, um es bestehen werden:

a[i] <- m.cpquery(network, (C=='c'), evi) 

Beachten Sie, dass In der ersten Zeile von m.cpquery haben wir nur die Variable evidence character analysiert und eval darauf nicht aufgerufen. cpquery ist ein Front-End zu conditional.probability.query (siehe here) und wir verlassen uns auf conditional.probability.query 's nachfolgenden Aufruf an eval.

Ich sollte sagen, dass dies eine ziemlich hässliche Problemumgehung ist. Und es funktioniert nur, wenn Sie Logik Sampling (method='ls') verwenden. Aber wenn Sie Likelihood Wichtung verwenden möchten, wird die check.mutilated.evidence Funktion einen Fehler auslösen. Ich habe nicht überprüft, ob das Eingeben eines Ausdrucks eval, bevor es aufgerufen wird, zu einem Chaos von nachfolgenden Fehlern führen würde, die zur Hölle führen.