diff --git a/NAMESPACE b/NAMESPACE index 2717381..b2c604d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -33,7 +33,6 @@ export(cpt) export(customNode) export(expectedParameters) export(expectedVariables) -export(factorFormula) export(fromData) export(fromFormula) export(inputCPT) diff --git a/R/factorFormula.R b/R/factorFormula.R index c241655..5e1191f 100644 --- a/R/factorFormula.R +++ b/R/factorFormula.R @@ -1,5 +1,4 @@ #' @name factorFormula -#' @export factorFormula #' @importFrom stringr str_extract_all #' @importFrom stringr str_split_fixed #' @@ -28,6 +27,7 @@ #' @author Jarrod Dalton and Benjamin Nutter #' #' @examples +#' \dontrun{ #' Net <- HydeNetwork(~ wells + #' pe | wells + #' d.dimer | pregnant*pe + @@ -37,6 +37,7 @@ #' data = PE) #' factorFormula(form = payoff ~ (death == 'No') + (pe == 'Yes'), #' network = Net) +#' } #' factorFormula <- function(form, network){ form <- deparse(form) diff --git a/R/setNode.R b/R/setNode.R index d613f94..4aa7e02 100644 --- a/R/setNode.R +++ b/R/setNode.R @@ -16,7 +16,9 @@ #' @param nodeFitter the fitting function, such as \code{lm} or \code{glm}. This #' will probably only be needed when \code{fromData = TRUE}. #' @param nodeFormula A formula object specifying the relationship between a -#' node and its parents. It must use as a term every parent of \code{node}. +#' node and its parents. It must use as a term every parent of \code{node}. This formula +#' will be pushed through the unexported function \code{factorFormula}. See +#' "Coding Factor Levels" for more details. #' @param fitterArgs Additional arguments to be passed to \code{fitter}. This does not #' yet have any effect as I haven't yet decided out where to store this and #' how to implement the fitting. @@ -86,6 +88,23 @@ #' will cause the model to be fit and the JAGS code for the parameters to be #' stored in the \code{nodeParams} attribute. #' +#' @section Coding Factor Levels: +#' The \code{nodeFormula} argument will accept any valid R formula. If desired, you +#' may use a specific formulation to indicate the presence of factor levels in the +#' formula. For instance, consider the case of a variable \code{y} with a binary +#' categorical parent \code{x} coded as 0 = No, and 1 = Yes. JAGS expects the +#' formula \code{y ~ c * x == 1} (where \code{c} is a constant). However, in +#' factor variables with a large number of levels, it can be difficult to remember +#' what value corresponds to what level. +#' +#' \code{HydeNet} uses an internal (unexported) function within \code{setNode} to allow +#' an alternate specification: \code{y ~ c * (x == "Yes")}. So long as the factors in +#' the formula are previously defined within the network structure, \code{HydeNet} +#' will translate the level into its numeric code. +#' +#' Note that it is required to write \code{x == "Yes"}. \code{"Yes" == x} will not +#' translate correctly. +#' #' @section Validation: #' The validation of parameters is performed by comparing the values provided with #' the limits defined in the \code{jagsDists$paramLogic} variable. (look at @@ -234,7 +253,7 @@ setNode <- function(network, node, nodeType, } if (length(list(...))) network$nodeParams[[node.t]] <- list(...) - if (!missing(nodeFormula)) network$nodeFormula[[node.t]] <- nodeFormula + if (!missing(nodeFormula)) network$nodeFormula[[node.t]] <- factorFormula(nodeFormula, network) if (!missing(nodeFitter)) network$nodeFitter[[node.t]] <- nodeFitter if (length(fitterArgs)) network$nodeFitterArgs[[node.t]] <- fitterArgs if (!is.null(nodeData)) network$nodeData[[node.t]] <- nodeData diff --git a/man/factorFormula.Rd b/man/factorFormula.Rd index 4780bb9..9597b3c 100644 --- a/man/factorFormula.Rd +++ b/man/factorFormula.Rd @@ -32,6 +32,7 @@ It is assumed that factor variables will be used in logical \code{factorFormula} may require writing native JAGS code. } \examples{ +\dontrun{ Net <- HydeNetwork(~ wells + pe | wells + d.dimer | pregnant*pe + @@ -42,6 +43,7 @@ Net <- HydeNetwork(~ wells + factorFormula(form = payoff ~ (death == 'No') + (pe == 'Yes'), network = Net) } +} \author{ Jarrod Dalton and Benjamin Nutter } diff --git a/man/setNode.Rd b/man/setNode.Rd index 29d1f16..583bb85 100644 --- a/man/setNode.Rd +++ b/man/setNode.Rd @@ -28,7 +28,9 @@ in \code{data(jagsDists)} for a complete list.} will probably only be needed when \code{fromData = TRUE}.} \item{nodeFormula}{A formula object specifying the relationship between a -node and its parents. It must use as a term every parent of \code{node}.} +node and its parents. It must use as a term every parent of \code{node}. This formula +will be pushed through the unexported function \code{factorFormula}. See +"Coding Factor Levels" for more details.} \item{fitterArgs}{Additional arguments to be passed to \code{fitter}. This does not yet have any effect as I haven't yet decided out where to store this and @@ -114,6 +116,25 @@ The functions \code{fromFormula()} and \code{fromData()} help to control will cause the model to be fit and the JAGS code for the parameters to be stored in the \code{nodeParams} attribute. } +\section{Coding Factor Levels}{ + +The \code{nodeFormula} argument will accept any valid R formula. If desired, you +may use a specific formulation to indicate the presence of factor levels in the +formula. For instance, consider the case of a variable \code{y} with a binary +categorical parent \code{x} coded as 0 = No, and 1 = Yes. JAGS expects the +formula \code{y ~ c * x == 1} (where \code{c} is a constant). However, in +factor variables with a large number of levels, it can be difficult to remember +what value corresponds to what level. + +\code{HydeNet} uses an internal (unexported) function within \code{setNode} to allow +an alternate specification: \code{y ~ c * (x == "Yes")}. So long as the factors in +the formula are previously defined within the network structure, \code{HydeNet} +will translate the level into its numeric code. + +Note that it is required to write \code{x == "Yes"}. \code{"Yes" == x} will not +translate correctly. +} + \section{Validation}{ The validation of parameters is performed by comparing the values provided with diff --git a/vignettes/DecisionNetworks.Rmd b/vignettes/DecisionNetworks.Rmd index 1697209..61c40ba 100644 --- a/vignettes/DecisionNetworks.Rmd +++ b/vignettes/DecisionNetworks.Rmd @@ -285,7 +285,7 @@ Alternatively, decision nodes can be deterministic in nature. In this case, we i ```{r} net <- setNode(net, payoff, "determ", define=fromFormula(), - nodeFormula = factorFormula(payoff ~ + nodeFormula = payoff ~ ifelse(playerFinalPoints > 21, -1, ifelse(playerFinalPoints == 21, ifelse(dealerOutcome == "Blackjack", 0, @@ -304,8 +304,7 @@ net <- setNode(net, payoff, "determ", define=fromFormula(), ifelse(dealerOutcome == "20", ifelse(playerFinalPoints == 20, 0, ifelse(playerFinalPoints > 20, 1, -1)), - ifelse(playerFinalPoints == 21, 0, -1)))))))), - net)) + ifelse(playerFinalPoints == 21, 0, -1))))))))) ```