2013-10-08 33 views
5

我試圖使用bnlearnpackage來計算條件概率,並且在循環中使用"cpquery"函數時遇到問題。我使用包中包含的數據創建了一個示例,如下所示。在循環中使用cpquery函數時,循環中創建的變量(示例中的「evi」)不被函數識別。我收到錯誤:在循環中使用bnlearn函數「cpquery」

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

「evi」的創建步驟基於作者提供的示例。

你可以提供的任何幫助將是偉大的。我非常渴望找到一種方法,可以將cpquery函數用於大量的觀察。

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) 

在此先感謝!

+1

我一直在和bnlearn軟件包的作者聯繫,看來我收到的錯誤是由於cpquery函數的範圍問題。這是顯而易見的,當我能夠讓cpquery函數在用戶定義函數的_outside_構造的for循環中正常工作,但在使用相同的for循環時出現錯誤_inside_用戶定義功能。 –

回答

0

爲避免範圍界定問題,您可以將呼叫推遲至eval,並在內部cpquery函數中執行。如果您直接將evi(字符變量)傳遞到cpquery,然後將其解析到定義中,則環境鏈將獲得轉移cpquery將有權訪問evi

您可以使用m.cpquery <- edit(cpqurey)到餐桌自己版本的函數,並在其開頭插入以下行:

evidence = parse(text = evidence) 

,然後保存您的新功能。 所以m.cpquery標題看起來像:

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

現在,你可以在自己的函數中使用m.cpquery像以前一樣,除了我們會通過簡單的字符變量給它:

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

注意在m.cpquery的第一行,我們只解析了證據字符變量,並沒有對其調用evalcpqueryconditional.probability.query的前端(請參閱here),我們依靠conditional.probability.queryeval的後續調用。

我應該說這是一個相當醜陋的解決方法。只有在使用邏輯採樣method='ls')時纔有效。但是如果您想使用似然權重,則check.mutilated.evidence函數將引發錯誤。我沒有檢查,如果在被調用之前注入一個eval表達式會導致隨後導致地獄的錯誤的混亂。