From 0768888b537500be98fd118bca0adb80ee96cd90 Mon Sep 17 00:00:00 2001
From: "Pavel N. Krivitsky"
Date: Tue, 13 Jul 2021 16:16:53 +1000
Subject: [PATCH] check.ErgmTerm() now only allows a NULL argument if 1) it's
listed in the vartypes explicitly or 2) it's optional and the default is
NULL; new constant, ERGM_VATTR_SPEC_NULL has been defined, equivalent to
ERGM_VATTR_SPEC plus NULL.
fixes statnet/ergm#349
---
DESCRIPTION | 2 +-
NAMESPACE | 1 +
R/check.ErgmTerm.R | 11 ++++++++---
R/get.node.attr.R | 4 ++++
man/check.ErgmTerm.Rd | 6 +++++-
man/ergm_model.Rd | 1 -
man/nodal_attributes-API.Rd | 5 +++++
7 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/DESCRIPTION b/DESCRIPTION
index 4e44c5439..61c4a51ac 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,5 +1,5 @@
Package: ergm
-Version: 4.0-6570
+Version: 4.0-6572
Date: 2021-07-13
Title: Fit, Simulate and Diagnose Exponential-Family Models for Networks
Authors@R: c(
diff --git a/NAMESPACE b/NAMESPACE
index 5c03fc06b..bcf0edc49 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -160,6 +160,7 @@ export(ERGM_STATE_C_CHANGED)
export(ERGM_STATE_RECONCILED)
export(ERGM_STATE_R_CHANGED)
export(ERGM_VATTR_SPEC)
+export(ERGM_VATTR_SPEC_NULL)
export(LARGEST)
export(SMALLEST)
export(approx.hotelling.diff.test)
diff --git a/R/check.ErgmTerm.R b/R/check.ErgmTerm.R
index e020c5b1b..c1cbf0c6f 100644
--- a/R/check.ErgmTerm.R
+++ b/R/check.ErgmTerm.R
@@ -41,7 +41,7 @@ ergm_Init_warn_once <- once(ergm_Init_warn)
#' @param varnames the vector of names of the possible arguments for
#' term X; default=NULL
#' @param vartypes the vector of types of the possible arguments for
-#' term X, separated by commas; an empty string (`""`) or `NA` disables the check for that argument; default=NULL
+#' term X, separated by commas; an empty string (`""`) or `NA` disables the check for that argument, and also see Details; default=NULL
#' @param defaultvalues the list of default values for the possible
#' arguments of term X; default=list()
#' @param required the logical vector of whether each possible
@@ -58,6 +58,10 @@ ergm_Init_warn_once <- once(ergm_Init_warn)
#' containing a named logical vector indicating whether a particular
#' argument had been set to its default.
#'
+#' @details As a convenience, if an argument is optional *and* its
+#' default is `NULL`, then `NULL` is assumed to be an acceptable
+#' argument type as well.
+#'
#' @import network
#' @export check.ErgmTerm
check.ErgmTerm <- function(nw, arglist, directed=NULL, bipartite=NULL, nonnegative=FALSE,
@@ -127,8 +131,9 @@ check.ErgmTerm <- function(nw, arglist, directed=NULL, bipartite=NULL, nonnegati
val <- out[[m]]
# Check type
- if(!is.na(vartypes[m]) && nchar(vartypes[m])
- && all(sapply(strsplit(vartypes[m],",",fixed=TRUE)[[1]], function(vartype) !is.null(val) && !is(val, vartype))))
+ if(!is.na(vartypes[m]) && nchar(vartypes[m]) &&
+ !(is.null(val) && !required[[m]] && is.null(defaultvalues[[m]])) &&
+ all(sapply(strsplit(vartypes[m],",",fixed=TRUE)[[1]], function(vartype) !is(val, vartype))))
ergm_Init_abort(sQuote(name), " argument is not of any of the expected (", vartypes[m], ") types.")
# Check deprecation (but only if passed explicitly)
diff --git a/R/get.node.attr.R b/R/get.node.attr.R
index 4f6d58caf..254aeb84d 100644
--- a/R/get.node.attr.R
+++ b/R/get.node.attr.R
@@ -644,6 +644,10 @@ ergm_attr_levels.formula <- function(object, attr, nw, levels=sort(unique(attr))
#' @export
ERGM_VATTR_SPEC <- "function,formula,character,AsIs"
+#' @rdname nodal_attributes-API
+#' @export
+ERGM_VATTR_SPEC_NULL <- "function,formula,character,AsIs,NULL"
+
#' @rdname nodal_attributes-API
#' @export
ERGM_LEVELS_SPEC <- "function,formula,character,numeric,logical,AsIs,NULL,matrix"
diff --git a/man/check.ErgmTerm.Rd b/man/check.ErgmTerm.Rd
index 7800ea14c..f06fac7f1 100644
--- a/man/check.ErgmTerm.Rd
+++ b/man/check.ErgmTerm.Rd
@@ -36,7 +36,7 @@ nonnegative weights; default=FALSE}
term X; default=NULL}
\item{vartypes}{the vector of types of the possible arguments for
-term X, separated by commas; an empty string (\code{""}) or \code{NA} disables the check for that argument; default=NULL}
+term X, separated by commas; an empty string (\code{""}) or \code{NA} disables the check for that argument, and also see Details; default=NULL}
\item{defaultvalues}{the list of default values for the possible
arguments of term X; default=list()}
@@ -76,4 +76,8 @@ network \item has an appropiate number of arguments \item has
correct argument types if arguments where provided \item has
default values assigned if defaults are available } by halting
execution if any of the first 3 criteria are not met.
+
+As a convenience, if an argument is optional \emph{and} its
+default is \code{NULL}, then \code{NULL} is assumed to be an acceptable
+argument type as well.
}
diff --git a/man/ergm_model.Rd b/man/ergm_model.Rd
index 0066c569d..1a88aaaf9 100644
--- a/man/ergm_model.Rd
+++ b/man/ergm_model.Rd
@@ -76,7 +76,6 @@ coefficients for each term.}
\value{
\code{ergm_model} returns an \code{ergm_model} object as a list
containing:
-\item{coef.names}{a vector of coefficient names}
\item{terms}{a list of terms and 'term components' initialized by the
appropriate \code{InitErgmTerm.X} function.}
\item{etamap}{the theta -> eta mapping as a list returned from
diff --git a/man/nodal_attributes-API.Rd b/man/nodal_attributes-API.Rd
index a9b3c6ea8..bc21ac3e7 100644
--- a/man/nodal_attributes-API.Rd
+++ b/man/nodal_attributes-API.Rd
@@ -19,6 +19,7 @@
\alias{ergm_attr_levels.function}
\alias{ergm_attr_levels.formula}
\alias{ERGM_VATTR_SPEC}
+\alias{ERGM_VATTR_SPEC_NULL}
\alias{ERGM_LEVELS_SPEC}
\title{Helper functions for specifying nodal attribute levels}
\format{
@@ -26,6 +27,8 @@ An object of class \code{character} of length 3.
An object of class \code{character} of length 1.
+An object of class \code{character} of length 1.
+
An object of class \code{character} of length 1.
}
\usage{
@@ -96,6 +99,8 @@ ergm_attr_levels(object, attr, nw, levels = sort(unique(attr)), ...)
ERGM_VATTR_SPEC
+ERGM_VATTR_SPEC_NULL
+
ERGM_LEVELS_SPEC
}
\arguments{