R中的评估和环境:为什么可以';t Eval()查找在计算表达式的环境中定义的变量

R中的评估和环境:为什么可以';t Eval()查找在计算表达式的环境中定义的变量,r,R,我有一个关于表达式求值环境的问题。具体来说,我有一个函数bnlearn::cpdist,它将逻辑表达式作为参数。我希望使用一个变量来指定那个参数,所以我希望使用eval(parse(text=string))。但是,如果这种情况发生在较大函数的环境中,eval函数无法找到变量“string”,尽管它是在该环境中定义的。我很困惑。这是重现问题的代码 # The function is from the bnlearn package, which handles Bayesian networks

我有一个关于表达式求值环境的问题。具体来说,我有一个函数bnlearn::cpdist,它将逻辑表达式作为参数。我希望使用一个变量来指定那个参数,所以我希望使用eval(parse(text=string))。但是,如果这种情况发生在较大函数的环境中,eval函数无法找到变量“string”,尽管它是在该环境中定义的。我很困惑。这是重现问题的代码

# The function is from the bnlearn package, which handles Bayesian networks
library(bnlearn)
#Example data
data(learning.test)
#Fitting a model
fitted = bn.fit(hc(learning.test), learning.test)
#The function in question generates samples from the PDF of one node given the values of others.  
posterior = cpdist(fitted, "D", (A == "a" & C == "b")) #Notice the awkward logical statement arg
prop.table(table(posterior))

#I want to use character variables instead of the logical statement.
#If I use parse and eval to specify the logical statement I have no issues.
evidence.nodes <- c("A", "C")
evidence.values <- c("a", "b")
ev <- paste("(", evidence.nodes, "=='",
                  sapply(evidence.values, as.character), "')",
                  sep = "", collapse = " & ")
posterior <- cpdist(fitted, "D", eval(parse(text = ev)))


#But what I want to do is apply do this from within a function
getPosterior <- function(fitted, target, ev.nodes, ev.values){
    ev <- paste("(", ev.nodes, "=='",
                  sapply(ev.values, as.character), "')",
                  sep = "", collapse = " & ")

     posterior <- cpdist(fitted, "D", eval(parse(text = ev)))
     prop.table(table(posterior))
}

#Here is where the problem lies.  The following works if "ev" is already defined as it was above.  However, if you remove ev from the global environment, then it fails.  I do not understand why it cannot find the ev object defined within the function's environment.

new.data <- data.frame(A = c("a", "b", "a", "b"), C = c("a", "a", "b", "b"))    
rm(ev)
for(i in 1:nrow(new.data)){
    print(getPosterior(fitted, "D", names(new.data), new.data[i, ]))    
}   
#该函数来自处理贝叶斯网络的bnlearn包
图书馆(bnlearn)
#示例数据
数据(学习、测试)
#拟合模型
拟合=bn.拟合(hc(学习.测试),学习.测试)
#该函数根据给定的其他节点的值,从一个节点的PDF生成样本。
posterior=cpdist(fitted,“D”,“A==”A“&C==”b”)#注意笨拙的逻辑语句arg
道具台(台(后))
#我想使用字符变量而不是逻辑语句。
#如果我使用parse和eval来指定逻辑语句,我就没有问题了。

我遇到过这样的问题。我用在函数中找不到的变量上的超级赋值来解决它

var <<- 5

var这里有很多问题,但首先,错误来自
parse()
而不是
eval()
。如果您解决了这个问题,那么您将得到另一个错误,这次是从
eval()
中得到的。您希望表达式
ev
(来自
getPosterior()
)在何处或在哪个对象中求值?例如,它应该在哪里找到
A
等。您在eval()中提出了一个关于变量范围的简单问题,但您提供了过于复杂和不相关的代码。。。(-1,对不起)我投票结束了你对这个问题的讨论,因为这个问题实际上是一个改进(IMHO)。谢谢你的评论。我给出代码是因为人们似乎希望能够重现错误。我不明白的是,代码works eval()可以在全局环境中定义“ev”对象时找到它,但在函数中定义时却找不到。