Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

search.ergmTerms behavior -- returns bipartite terms for non-bipartite network #571

Open
martinamorris opened this issue Jul 12, 2024 · 6 comments

Comments

@martinamorris
Copy link
Member

martinamorris commented Jul 12, 2024

According to the help:

Argument function
search optional character search term to search for in the text of the term descriptions. Only matching terms will be returned. Matching is case insensitive.
net a network object that the term would be applied to, used as template to determine directedness, bipartite, etc
keywords optional character vector of keyword tags to use to restrict the results (i.e. 'curved', 'triad-related')
name optional character name of a specific term to return
packages optional character vector indicating the subset of packages in which to search
reference, constraints optional names of references and constraints to narrow down the proposal

But the function returns bipartite terms for the non-bipartite faux.mesa.high net:

reprex({
  library(ergm)
  data(faux.mesa.high)
  faux.mesa.high
  search.ergmTerms(net=faux.mesa.high)
})

library(ergm)
#> Loading required package: network
#>
#> 'network' 1.18.2 (2023-12-04), part of the Statnet Project
#> * 'news(package="network")' for changes since last version
#> * 'citation("network")' for citation information
#> * 'https://statnet.org' for help, support, and other information
#>
#> 'ergm' 4.6.0 (2023-12-17), part of the Statnet Project
#> * 'news(package="ergm")' for changes since last version
#> * 'citation("ergm")' for citation information
#> * 'https://statnet.org' for help, support, and other information
#> 'ergm' 4 is a major update that introduces some backwards-incompatible
#> changes. Please type 'news(package="ergm")' for a list of major
#> changes.
data(faux.mesa.high)
faux.mesa.high
#> Network attributes:
#> vertices = 205
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = FALSE
#> total edges= 203
#> missing edges= 0
#> non-missing edges= 203
#>
#> Vertex attribute names:
#> Grade Race Sex
#>
#> No edge attributes
search.ergmTerms(net=faux.mesa.high)
#> Found 78 matching ergm terms:
#> absdiff(attr, pow=1) (binary)
#> absdiff(attr, pow=1, form="sum") (valued)
#> Absolute difference in nodal attribute
#>
#> absdiffcat(attr, base=NULL, levels=NULL) (binary)
#> absdiffcat(attr, base=NULL, levels=NULL, form="sum") (valued)
#> Categorical absolute difference in nodal attribute
#>
#> altkstar(lambda, fixed=FALSE) (binary)
#> Alternating k-star
#>
#> atleast(threshold=0) (valued)
#> Number of dyads with values greater than or equal to a threshold
#>
#> atmost(threshold=0) (valued)
#> Number of dyads with values less than or equal to a threshold
#>
#> attrcov(attr, mat) (binary)
#> Edge covariate by attribute pairing
#>
#> b1concurrent(by=NULL, levels=NULL) (binary)
#> Concurrent node count for the first mode in a bipartite network
#>
#> b1cov(attr) (binary)
#> b1cov(attr, form="sum") (valued)
#> Main effect of a covariate for the first mode in a bipartite network
#>
#> b1degrange(from, to=+Inf, by=NULL, homophily=FALSE, levels=NULL) (binary)
#> Degree range for the first mode in a bipartite network
#>
#> b1degree(d, by=NULL, levels=NULL) (binary)
#> Degree for the first mode in a bipartite network
#>
#> b1dsp(d) (binary)
#> Dyadwise shared partners for dyads in the first bipartition
#>
#> b1factor(attr, base=1, levels=-1) (binary)
#> b1factor(attr, base=1, levels=-1, form="sum") (valued)
#> Factor attribute effect for the first mode in a bipartite network
#>
#> b1mindegree(d) (binary)
#> Minimum degree for the first mode in a bipartite network
#>
#> b1nodematch(attr, diff=FALSE, keep=NULL, alpha=1, beta=1, byb2attr=NULL, levels=NULL) (binary)
#> Nodal attribute-based homophily effect for the first mode in a bipartite network
#>
#> b1sociality(nodes=-1) (binary)
#> b1sociality(nodes=-1, form="sum") (valued)
#> Degree
#>
#> b1star(k, attr=NULL, levels=NULL) (binary)
#> k-stars for the first mode in a bipartite network
#>
#> b1starmix(k, attr, base=NULL, diff=TRUE) (binary)
#> Mixing matrix for k-stars centered on the first mode of a bipartite network
#>
#> b1twostar(b1attr, b2attr, base=NULL, b1levels=NULL, b2levels=NULL, levels2=NULL) (binary)
#> Two-star census for central nodes centered on the first mode of a bipartite network
#>
#> b2concurrent(by=NULL) (binary)
#> Concurrent node count for the second mode in a bipartite network
#>
#> b2cov(attr) (binary)
#> b2cov(attr, form="sum") (valued)
#> Main effect of a covariate for the second mode in a bipartite network
#>
#> b2degrange(from, to=+Inf, by=NULL, homophily=FALSE, levels=NULL) (binary)
#> Degree range for the second mode in a bipartite network
#>
#> b2degree(d, by=NULL) (binary)
#> Degree for the second mode in a bipartite network
#>
#> b2dsp(d) (binary)
#> Dyadwise shared partners for dyads in the second bipartition
#>
#> b2factor(attr, base=1, levels=-1) (binary)
#> b2factor(attr, base=1, levels=-1, form="sum") (valued)
#> Factor attribute effect for the second mode in a bipartite network
#>
#> b2mindegree(d) (binary)
#> Minimum degree for the second mode in a bipartite network
#>
#> b2nodematch(attr, diff=FALSE, keep=NULL, alpha=1, beta=1, byb1attr=NULL, levels=NULL) (binary)
#> Nodal attribute-based homophily effect for the second mode in a bipartite network
#>
#> b2sociality(nodes=-1) (binary)
#> b2sociality(nodes=-1, form="sum") (valued)
#> Degree
#>
#> b2star(k, attr=NULL, levels=NULL) (binary)
#> k-stars for the second mode in a bipartite network
#>
#> b2starmix(k, attr, base=NULL, diff=TRUE) (binary)
#> Mixing matrix for k-stars centered on the second mode of a bipartite network
#>
#> b2twostar(b1attr, b2attr, base=NULL, b1levels=NULL, b2levels=NULL, levels2=NULL) (binary)
#> Two-star census for central nodes centered on the second mode of a bipartite network
#>
#> balance (binary)
#> Balanced triads
#>
#> coincidence(levels=NULL,active=0) (binary)
#> Coincident node count for the second mode in a bipartite (aka two-mode) network
#>
#> concurrent(by=NULL, levels=NULL) (binary)
#> Concurrent node count
#>
#> concurrentties(by=NULL, levels=NULL) (binary)
#> Concurrent tie count
#>
#> cycle(k, semi=FALSE) (binary)
#> k-Cycle Census
#>
#> cyclicalties(attr=NULL, levels=NULL) (binary)
#> cyclicalties(threshold=0) (valued)
#> Cyclical ties
#>
#> cyclicalweights(twopath="min", combine="max", affect="min") (valued)
#> Cyclical weights
#>
#> degcor (binary)
#> Degree Correlation
#>
#> degcrossprod (binary)
#> Degree Cross-Product
#>
#> degrange(from, to=+Inf, by=NULL, homophily=FALSE, levels=NULL) (binary)
#> Degree range
#>
#> degree(d, by=NULL, homophily=FALSE, levels=NULL) (binary)
#> Degree
#>
#> degree1.5 (binary)
#> Degree to the 3/2 power
#>
#> density (binary)
#> Density
#>
#> diff(attr, pow=1, dir="t-h", sign.action="identity") (binary)
#> diff(attr, pow=1, dir="t-h", sign.action="identity", form ="sum") (valued)
#> Difference
#>
#> dyadcov(x, attrname=NULL) (binary)
#> Dyadic covariate
#>
#> edgecov(x, attrname=NULL) (binary)
#> edgecov(x, attrname=NULL, form="sum") (valued)
#> Edge covariate
#>
#> edges (binary, valued)
#> nonzero (valued)
#> Number of edges in the network
#>
#> equalto(value=0, tolerance=0) (valued)
#> Number of dyads with values equal to a specific value (within tolerance)
#>
#> greaterthan(threshold=0) (valued)
#> Number of dyads with values strictly greater than a threshold
#>
#> gwb1degree(decay, fixed=FALSE, attr=NULL, cutoff=30, levels=NULL) (binary)
#> Geometrically weighted degree distribution for the first mode in a bipartite network
#>
#> gwb1dsp(decay=0, fixed=FALSE, cutoff=30) (binary)
#> Geometrically weighted dyadwise shared partner distribution for dyads in the first bipartition
#>
#> gwb2degree(decay, fixed=FALSE, attr=NULL, cutoff=30, levels=NULL) (binary)
#> Geometrically weighted degree distribution for the second mode in a bipartite network
#>
#> gwb2dsp(decay=0, fixed=FALSE, cutoff=30) (binary)
#> Geometrically weighted dyadwise shared partner distribution for dyads in the second bipartition
#>
#> gwdegree(decay, fixed=FALSE, attr=NULL, cutoff=30, levels=NULL) (binary)
#> Geometrically weighted degree distribution
#>
#> hamming(x, cov, attrname=NULL) (binary)
#> Hamming distance
#>
#> ininterval(lower=-Inf, upper=+Inf, open=c(TRUE,TRUE)) (valued)
#> Number of dyads whose values are in an interval
#>
#> isolatededges (binary)
#> Isolated edges
#>
#> isolates (binary)
#> Isolates
#>
#> kstar(k, attr=NULL, levels=NULL) (binary)
#> k-stars
#>
#> localtriangle(x) (binary)
#> Triangles within neighborhoods
#>
#> meandeg (binary)
#> Mean vertex degree
#>
#> mm(attrs, levels=NULL, levels2=-1) (binary)
#> mm(attrs, levels=NULL, levels2=-1, form="sum") (valued)
#> Mixing matrix cells and margins
#>
#> nodecov(attr) (binary)
#> nodemain (binary)
#> nodecov(attr, form="sum") (valued)
#> nodemain(attr, form="sum") (valued)
#> Main effect of a covariate
#>
#> nodefactor(attr, base=1, levels=-1) (binary)
#> nodefactor(attr, base=1, levels=-1, form="sum") (valued)
#> Factor attribute effect
#>
#> nodematch(attr, diff=FALSE, keep=NULL, levels=NULL) (binary)
#> nodematch(attr, diff=FALSE, keep=NULL, levels=NULL, form="sum") (valued)
#> match(attr, diff=FALSE, keep=NULL, levels=NULL, form="sum") (valued)
#> Uniform homophily and differential homophily
#>
#> nodemix(attr, base=NULL, b1levels=NULL, b2levels=NULL, levels=NULL, levels2=-1) (binary)
#> nodemix(attr, base=NULL, b1levels=NULL, b2levels=NULL, levels=NULL, levels2=-1, form="sum") (valued)
#> Nodal attribute mixing
#>
#> opentriad (binary)
#> Open triads
#>
#> smalldiff(attr, cutoff) (binary)
#> Number of ties between actors with similar attribute values
#>
#> smallerthan(threshold=0) (valued)
#> Number of dyads with values strictly smaller than a threshold
#>
#> sociality(attr=NULL, base=1, levels=NULL, nodes=-1) (binary)
#> sociality(attr=NULL, base=1, levels=NULL, nodes=-1, form="sum") (valued)
#> Undirected degree
#>
#> sum(pow=1) (valued)
#> Sum of dyad values (optionally taken to a power)
#>
#> threetrail(keep=NULL, levels=NULL) (binary)
#> threepath(keep=NULL, levels=NULL) (binary)
#> Three-trails
#>
#> transitiveties(attr=NULL, levels=NULL) (binary)
#> Transitive ties
#>
#> transitiveweights(twopath="min", combine="max", affect="min") (valued)
#> Transitive weights
#>
#> triadcensus(levels) (binary)
#> Triad census
#>
#> triangle(attr=NULL, diff=FALSE, levels=NULL) (binary)
#> triangles(attr=NULL, diff=FALSE, levels=NULL) (binary)
#> Triangles
#>
#> tripercent(attr=NULL, diff=FALSE, levels=NULL) (binary)
#> Triangle percentage
#>
#> twopath (binary)
#> 2-Paths
Created on 2024-07-12 with reprex v2.1.1

@krivit
Copy link
Member

krivit commented Jul 13, 2024

This is related to #409, which we never resolved. Briefly, we can have keyword "bipartite" be set on terms that work on bipartite networks (including, e.g., absdiff) or on terms that only work on bipartite networks (e.g., b1cov). Carter and I had a back-and-forth, but there wasn't any resolution that was implemented.

@martinamorris
Copy link
Member Author

I wish the world was simpler. That said:

  1. I would vote in favor of the former -- I think most people will use the keyword to find terms that can be used in their networks, not the terms that can ONLY be used in their networks.

  2. We still shouldn't be returning bipartite only terms for non-bipartite nets.

@krivit
Copy link
Member

krivit commented Jul 13, 2024

I wish the world was simpler. That said:

1. I would vote in favor of the former -- I think most people will use the keyword to find terms that can be used in their networks, not the terms that can ONLY be used in their networks.

2. We still shouldn't be returning bipartite only terms for non-bipartite nets.

And therein lies the problem: you can have one or the other but not both.

Let's say we go with the "works on bipartite". Then, both absdiff and b1cov would have the keyword, so both will show up for a bipartite network; on the other hand, you then won't be able to use it to filter out b1cov on faux.mesa.high. So, we can do 1. but not 2..

@martinamorris
Copy link
Member Author

martinamorris commented Jul 15, 2024

Aha, so the problem is that we don't have a keyword for basic (unipartite, undirected, non-hyper, non-multiple, binary) nets like faux.mesa.high?

Is it possible to modify this code to exclude terms that start with "b" or "d" if the nw attributes are all "FALSE" for those conditions?

As a side note -- I'm not sure the keywords have been updated for "multiple". If so, the documentation hasn't.

@krivit
Copy link
Member

krivit commented Jul 16, 2024

Aha, so the problem is that we don't have a keyword for basic (unipartite, undirected, non-hyper, non-multiple, binary) nets like faux.mesa.high?

That could be a possible remedy. "Unipartite" is a very ugly word, but adding it to all terms but the explicitly bipartite ones should, in principle, solve the problem.

Is it possible to modify this code to exclude terms that start with "b" or "d" if the nw attributes are all "FALSE" for those conditions?

It's possible, but it would be a very bad idea to make assumptions about what a term does based on its name. A more reliable approach might be to try to parse the body of the Init*ErgmTerm.*() function and the check.ErgmTerm() call, I suppose, but that also assumes that the term author writes a term in a particular way.

As a side note -- I'm not sure the keywords have been updated for "multiple". If so, the documentation hasn't.

I am not sure what you mean. There is no "multiple" keywords; are you referring to binary vs. valued?

@martinamorris
Copy link
Member Author

I am not sure what you mean. There is no "multiple" keywords; are you referring to binary vs. valued?

no -- to multinet modeling terms, if there are any

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants