Classifies the node triples of a network into the 16 directed MAN triad types and tests their frequencies against a permutation null. The function has two modes.
In census mode (
named_nodes = FALSE, the default), the result counts the triads of each MAN type. Nodes are exchangeable.In instance mode (
named_nodes = TRUE, orsubgraphs()), the result lists the node triples that form each type.
Usage
motifs(
x,
named_nodes = FALSE,
actor = NULL,
window = NULL,
window_type = c("rolling", "tumbling"),
pattern = c("triangle", "network", "closed", "all"),
include = NULL,
exclude = NULL,
significance = TRUE,
n_perm = 1000L,
cores = 1L,
min_count = if (named_nodes) 2L else NULL,
edge_method = c("any", "expected", "percent"),
edge_threshold = 1.5,
min_transitions = if (named_nodes) 3 else 5,
top = NULL,
seed = NULL,
family = c("observed", "all"),
p_adjust = "none",
strict = TRUE,
count_repeats = FALSE
)
# S3 method for class 'cograph_motif_result'
as.data.frame(
x,
row.names = NULL,
optional = FALSE,
...,
what = c("results", "types"),
significant = FALSE
)Arguments
- x
Input data: a tna object, cograph_network, matrix, igraph object or edge-list data frame. An edge list has the columns
fromandto(any case), an optional weight columnweightorcount(1 per row otherwise), the optional actor column described underactor, and an optional order column (timestamp,time,seq,stepororder) that sorts the transitions within each actor before windowing. An edge list withoutfromortoraises an error of classcograph_bad_edgelist. Foras.data.frame(), acograph_motif_resultobject returned bymotifs()orsubgraphs().- named_nodes
Logical. If FALSE (default), the MAN type census is computed. If TRUE, the individual node triples are listed.
subgraphs()sets this to TRUE.- actor
Character. Name of the edge-list column that identifies the units. If NULL (default), the first column named
session_id,session,actor,user,participant,individualorid(in that order, ignoring case) is used. Without such a column the analysis is aggregate.- window
Numeric. Window size for edge-list input. Each actor's transitions are cut into windows of this many transitions, and every window is analysed as one unit (individual level).
windowneeds an actor column; without one it raises an error of classcograph_window_needs_actor. NULL (default) applies no windowing.- window_type
Character.
"rolling"(default) windows start at every transition and overlap;"tumbling"windows are consecutive and do not overlap. Used only whenwindowis set.- pattern
Which MAN triad types to include in the analysis:
"triangle"(default) The 7 closed triangle types 030C, 030T, 120C, 120D, 120U, 210 and 300.
"network"All types except 003 (empty), 012 (single edge) and 021C (chain).
"closed"The same 7 closed types as
"triangle": every pair of the three nodes is linked."all"All 16 MAN types.
- include
Character vector of MAN types to keep. When supplied,
patternandexcludeare ignored, and the result records the pattern as"custom".- exclude
Character vector of MAN types to drop in addition to those removed by
pattern.- significance
Logical. If TRUE (default), a permutation significance test is run. In instance mode the test requires individual data, and for aggregate input it is skipped with a warning.
- n_perm
Number of permutations for significance. When
significance = TRUE, must be a whole number of at least 2. Default 1000.- cores
Number of worker processes for the permutation null. Default 1 runs serially and draws all replicates from a single RNG stream.
cores > 1gives each replicate its own L'Ecuyer-CMRG stream, so the result depends onseedalone and is the same for every worker count. The serial and parallel streams differ, so a serial run and a parallel run with the same seed give different p-values. Forking is used where available, and Windows uses a PSOCK cluster. Only the individual-level census null is parallelized. Values aboveparallel::detectCores()are capped with acograph_cores_cappedwarning.- min_count
Inclusive minimum count for a row to be kept. In census mode it filters the
countcolumn, the number of triads of each MAN type. In instance mode it filters theobservedcolumn. At individual level this is the number of units showing the triad, and at aggregate level it is the weighted edge mass of the triad (the sum of its 6 directed edge weights). Default 2 in instance mode, since at individual level a pattern seen in a single unit cannot recur, and NULL (no filter) in census mode. At aggregate level the threshold applies to the edge weight mass, so for probability matrices lower it (for examplemin_count = 1orNULL).- edge_method
Method for determining edge presence:
"any"(default; any positive edge),"expected"(ratio of the observed weight to the weight expected from the row and column totals), or"percent"(edge weight divided by the six-edge triad total).- edge_threshold
Threshold for
"expected"or"percent"methods. For"expected", 1.5 means 50 percent above expected. For"percent", values at or below 1 are proportions and values above 1 are percentages. Default 1.5.- min_transitions
Minimum total edge weight for a unit to be included, counted after self-loops are removed unless
count_repeats = TRUE. Default 3 in instance mode, the fewest transitions that can form a closed triad (030C and 030T have three edges), and 5 in census mode. At aggregate level the network is the only unit, so a network whose weights sum to less than this value gives NULL; for a probability matrix setmin_transitions = 0.- top
Integer or NULL. Only the first
toprows of the results are kept. NULL (default) keeps all rows.- seed
Random seed. Default NULL. When supplied, the caller's RNG state is restored on exit.
- family
Which rows the instance-mode significance test covers.
"observed"(default) tests the triple-type rows observed in at leastmin_countunits."all"tests every node triple crossed with every retained MAN type, including combinations no unit shows, andmin_countthen filters only the rows returned. Testing only observed rows selects on the outcome: a rare configuration enters the test only when it happens to occur, which inflates the false-positive rate well above the nominal level."all"keeps it at or below the nominal level. The full family haschoose(n_states, 3)rows per retained labelled pattern withstrict = TRUE(for example six for 030T, two for 030C and one for 300), or per retained MAN type withstrict = FALSE, so the permutation null grows accordingly. Ignored in census mode and without individual-level significance.- p_adjust
Multiplicity correction applied to the p-values of every tested row, one of
p.adjust.methods. Default"none". The adjusted values are returned inp_adjandsigisp_adj < 0.05. Withfamily = "all"the adjustment covers the full family beforemin_countis applied. Plot colours and stars followp_adj, so they matchsig.- strict
Logical. In instance mode, whether a row is one labelled pattern of a triple (
TRUE, default) or one MAN type of a triple (FALSE). A MAN type fixes the shape of a triad but not which node plays which role: the cycles A to B to C to A and A to C to B to A are both 030C. Withstrict = TRUEthe two are separate rows, a unit counts toward a row only when the triple shows exactly that set of arrows, and the null counts the same exact pattern. Withstrict = FALSErows pool every labelled pattern of the type andpatternreports the most frequent one. Ignored in census mode.- count_repeats
Logical. Whether repeated codes (self-transitions such as A to A) count as transitions. Default
FALSE: repeats are removed before anything else, so only transitions between different codes decide which units are analysed and enter the permutation null. WithTRUE, repeats count towardmin_transitions(a unit coded A, A, A, B, C has four transitions instead of two) and are shuffled with the other transitions in the null, which treats repeated codes as distinct events whose order is random. The null then also reflects how often units repeat: units that repeat a lot have fewer ties between different codes than their shuffles, which raises the number of dense triads the null expects. Observed triads never contain a repeat in either case, because a triad is made of ties between three different nodes.- row.names, optional
Standard
as.data.framearguments.row.namesreplaces the default row names;optionalis ignored.- ...
Unused.
- what
Which table
as.data.frame()returns, either"results"(default) or"types". The Value section lists the columns of each.- significant
Logical. When
TRUE,as.data.frame()keeps only the rows whosesigflag isTRUE. It applies towhat = "results"and needs a result computed withsignificance = TRUE; otherwise acograph_no_significanceerror is raised. DefaultFALSE.
Value
A cograph_motif_result object, or NULL with a message when no
motif passes the filters. The object is a list with the elements below.
- results
Data frame of results. In census mode it has one row per retained, observed MAN type and the columns
typeandcount. In instance mode it has one row per node triple and labelled pattern (strict = TRUE) or per node triple and MAN type (strict = FALSE), with the columnstriad,node1,node2,node3,type,observed,pattern,pattern_nandpattern_code. At individual level,observedis the number of units in which the triple shows that pattern (or type), so one triple can occupy several rows.patternis the labelled edge set of the row (for example"A -> B, B <-> C"). Withstrict = FALSEa row pools patterns that differ in direction, sopatternis the most frequent of them andpattern_nthe number of units showing it; at individual level withstrict = TRUEpattern_nequalsobserved.pattern_codeis the same edge set as a six-bit code innode1,node2,node3order (1: node1 to node2, 2: node2 to node1, 4: node1 to node3, 8: node3 to node1, 16: node2 to node3, 32: node3 to node2). Modal ties go to the smallest code. Rows that no unit shows (family = "all") haveobserved = 0andpattern_n = 0; their pattern is the row's own pattern whenstrict = TRUEand missing otherwise. At aggregate levelpattern_nis 1. Withsignificance = TRUE, the columnsexpected(null mean),z,p,p_adjandsigare added, unrounded, and the rows are sorted by decreasing absolute z-score. Otherwise the rows are sorted by decreasing count. Census results carryexpected,z,p,p_adjandsigin the same way.- type_summary
Named
tableof counts per MAN type, sorted in decreasing order. In census mode it holds thecountcolumn. In instance mode it holds the number of result rows of each type: node triple and labelled pattern withstrict = TRUE, node triple and type withstrict = FALSE.- level
"individual"when the input carried per-unit data, otherwise"aggregate".- named_nodes
The value of the
named_nodesargument.- n_units
Number of units analyzed: the units whose transition total (loop-free unless
count_repeats = TRUE) reachesmin_transitions. 1 at aggregate level.- n_units_total
Number of units supplied, before the
min_transitionsfilter.- params
List of the analysis settings:
labels,n_states,pattern("custom"whenincludeis used),include,edge_method,edge_threshold,significance,n_perm,min_count,min_transitions,count_repeats,family,p_adjust,strict,window,window_typeandactor(the actor column used, or NULL at aggregate level).
as.data.frame() returns one of these tables as a plain data frame.
With what = "results" (default) it returns the results
table described above. With what = "types" it returns one row per
MAN type with columns type and count, where count is
the number of triads of that type in a census or the number of result
rows of that type in instance mode (see type_summary).
Details
The input type and the analysis level are detected automatically. Inputs
that carry per-unit data are analyzed per unit. These are tna objects,
networks that store sequence data (such as as_cograph() of a tna or
a network from Nestimate::build_network()), and edge lists (or
networks built from edge lists) with an actor column. Matrices, igraph
objects and other networks are analyzed as one aggregate network. The adjacency is always
classified as directed. The four-class undirected census is computed by
motif_census(..., directed = FALSE).
For aggregate inputs, significance is computed by motif_census()
with its degree-preserving rewiring null on the simple loop-free graph.
Individual weighted inputs use a directed stub-matching null. Each positive
edge weight is converted to at least one integer stub, and target stubs are
shuffled within each unit so that its integer in- and out-margins are
preserved. The resulting multigraph, which may contain loops or parallel
edges, is classified through its simple loop-free triad projection.
Self-loops are removed before counting. They are also removed before the
null is constructed, unless count_repeats = TRUE, in which case they
are shuffled with the other transitions.
With edge_method = "percent", edge presence is computed within each
node triple. The weight of an edge is divided by the sum of the six possible
directed edge weights of that triple. A threshold above 1 is read as a
percentage (1.5 means 1.5 percent), and a threshold at or below 1 is read
as a proportion.
With an edge_method other than "any", the significance test
has limits. For aggregate census input, the observed counts use the
threshold while the null tests the unthresholded network, and a warning is
raised. For individual census input, the threshold is reapplied to each
stub-null replicate. For individual instance input, the null classifies raw
stub presence and does not reapply edge_method or
edge_threshold. In every weighted individual null, a positive
fractional weight keeps at least one stub. This preserves the support but
can change the weight scale used by "percent" and "expected".
Descriptive results with significance = FALSE or
edge_method = "any" are unaffected.
Printing and plotting
Printing the result shows the analysis settings, the MAN type distribution
and the first 20 rows of the results table. as.data.frame() returns
the tidy tables. plot() on the result is documented in
plot-results.
Examples
census <- motifs(regulation_net, significance = FALSE)
as.data.frame(census, what = "types")
#> type count
#> 1 030T 11
#> 2 120C 3
#> 3 030C 2
#> 4 120D 2
#> 5 120U 1
