I have a question concerning environments in evaluating expressions. Specifically, I have a function bnlearn::cpdist that takes a logical expression as an argument. I wish to use a variable to specify that argument, so I wish to use eval(parse(text = string)). But in the case this is happening within the environment of a larger function, the eval function can't find the variable "string", despite it having been defined in that environment. I am confused. Here is the code the reproduces the problem.
# 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, ]))
}