When clusters are detected in each time window separately, their
identifiers mean nothing from one window to the next: cluster "01" of the
1975-1984 network and cluster "01" of the 1976-1985 network may be two
different literatures. merge_dynamic_clusters() links the clusters of
successive windows that share most of their nodes, and gives them a
common identifier, so that a cluster becomes an entity that can be born,
persist and disappear. This is the step that turns a series of networks
into a history of research communities, in the spirit of the alluvial
maps of Rosvall and Bergstrom (2010)
.
Two rules are available, chosen with method. Let \(V_a\) be the nodes
of cluster \(a\) in window \(t-1\) and \(V_b\) those of cluster
\(b\) in window \(t\).
method = "majority", a double majority. Cluster \(b\) inherits the identifier of \(a\) when most nodes of \(a\) go to \(b\) and most nodes of \(b\) come from \(a\): $$\frac{|V_a \cap V_b|}{D_a} > \tau \quad \text{and} \quad \frac{|V_a \cap V_b|}{D_b} > \tau,$$ with \(\tau\) thethreshold_similarity, strictly above 0.5. Since \(\tau > 0.5\), a cluster can inherit at most one identifier, and an identifier passes to at most one cluster.method = "jaccard", an overlap matching with a Jaccard threshold, as in the tracking of dynamic communities of Greene et al. (2010) . The Jaccard index of two clusters is the share of their union that they have in common, $$J(a, b) = \frac{|V_a \cap V_b|}{|V_a \cup V_b|}.$$ The pairs with \(J(a, b) \geq \theta\), \(\theta\) being thethreshold_similarity, are candidate matches. They are taken one by one, by decreasing \(J\) (then by decreasing number of shared nodes), skipping the pairs where \(a\) or \(b\) has already been matched: each past identifier goes to the present cluster that resembles it most, and each cluster inherits at most one identifier. \(\theta\) can be below 0.5: a cluster that loses a large part of its members to another cluster, or that doubles with newcomers, can keep its identity if it stays the best match of its predecessor.
In both rules, a cluster that meets no match gets a new identifier. The
sets \(V\) depend on similarity_type: with "complete", they are all
the nodes of the clusters (\(D_a = |V_a|\), \(D_b = |V_b|\)); with
"partial", only the nodes present in both windows count
(\(D_a = |V_a \cap V_t|\), \(D_b = |V_b \cap V_{t-1}|\), and the union
of the Jaccard index is restricted to them), \(V_t\) being all the nodes
of window \(t\).
There is no default method, threshold_similarity or similarity_type:
they change the dynamic clusters, so the choice must be explicit, and
verbose = TRUE reports the rule that is applied.
Arguments
- graphs
A list of at least two
tbl_graphs in chronological order (oldest first), as produced bybuild_dynamic_networks()andadd_clusters().- cluster_id
Character scalar, the node column with the clusters of each window (e.g.
"cluster_leiden").- node_id
Character scalar, the node column with an identifier that is stable across windows (e.g.
"source_id").- method
"majority"(double majority) or"jaccard"(overlap matching with a Jaccard threshold), see the description. Required.- threshold_similarity
The threshold of the rule. For
method = "majority", \(\tau\) in \((0.5, 1]\): a cluster is linked when the share is above it. Formethod = "jaccard", \(\theta\) in \((0, 1]\): two clusters can be linked when their Jaccard index is at least it. Higher values require more similar clusters and create more distinct dynamic clusters. Required.- similarity_type
"complete"or"partial", see the description. Required.- verbose
Logical. If
TRUE(default), says which rule is applied.
Value
The list of graphs, with the same names, where nodes have a new
column dynamic_{cluster_id} (e.g. dynamic_cluster_leiden, with
identifiers "cl_1", "cl_2"...) and edges the columns
dynamic_{cluster_id}_from, dynamic_{cluster_id}_to and
dynamic_{cluster_id} (missing for edges between clusters).
Details
Which windows? The rules need nodes present in successive windows.
In a network of documents (e.g. bibliographic coupling), each document has
a single date, so windows that do not overlap (window_step equal to
time_window, the default of build_dynamic_networks()) share no node
and no cluster can be matched: the windows must overlap
(window_step smaller than time_window). Non-overlapping windows work
when nodes persist over time, as cited references (co-citation), authors or
journals do; two windows may still share no node when the literature
changed completely.
Complete or partial? With overlapping windows, the network of window
\(t\) loses the documents of the first years of window \(t-1\) and
gains those of new years; in a growing literature, newcomers can be
numerous. With "complete", a cluster that keeps all its past members but
doubles with newcomers cannot inherit the identifier under the double
majority, because its members coming from \(a\) are less than half of it:
the cluster is considered new because its composition changed. With
"partial", the newcomers are ignored and the same cluster keeps its
identifier. Which one is right depends on what a cluster is taken to be: a
group of documents (complete), or a structure that recruits new documents
(partial).
Majority or Jaccard? The double majority is demanding and
transparent: two clusters are the same if each is mostly made of the
other, and the identifier is never ambiguous. The Jaccard matching is more
flexible: with a low \(\theta\), it follows a cluster that splits (the
largest piece, the best match, keeps the identifier) or that merges with
another. Both use the nodes of consecutive windows only; compare them
with merge_diagnostics().
What the rules do not do. Clusters are compared only with the previous window: a cluster that vanishes for one window and comes back gets a new identifier. Splits and merges are not recorded as such: one part keeps the identifier, the others are new. With a threshold close to its minimum, small fluctuations of the partition (a stochastic algorithm, a resolution change) may break or create continuities; it is good practice to compare the results for a few thresholds and seeds.
References
Greene D, Doyle D, Cunningham P (2010).
“Tracking the Evolution of Communities in Dynamic Social Networks.”
In 2010 International Conference on Advances in Social Networks Analysis and Mining, 176–183.
doi:10.1109/ASONAM.2010.17
.
Rosvall M, Bergstrom CT (2010).
“Mapping Change in Large Networks.”
PLoS ONE, 5(1), e8694.
doi:10.1371/journal.pone.0008694
.
See also
name_clusters() with name_dynamic_clusters = TRUE to label the
dynamic clusters; networks_to_alluv() and plot_alluvial() to draw
their evolution.
Examples
networks <- build_dynamic_networks(
nodes = subset(Nodes_stagflation, source_type == "Stagflation"),
directed_edges = Ref_stagflation,
source_id = "source_id",
target_id = "target_id",
time_variable = "source_year",
time_window = 10,
method = "similarity",
edges_threshold = 1,
verbose = FALSE
)
#> Warning: The last window is shorter than the others.
#> ℹ The data end in "2013", but the last window ends in "2014".
networks <- add_clusters(
networks,
clustering_method = "leiden",
objective_function = "modularity",
seed = 123,
verbose = FALSE
)
networks <- merge_dynamic_clusters(
networks,
cluster_id = "cluster_leiden",
node_id = "source_id",
method = "majority",
threshold_similarity = 0.51,
similarity_type = "partial"
)
#> ℹ Linking clusters across windows with the "majority" rule: a cluster inherits
#> the identifier of a past cluster when more than 0.51 of the nodes of each go
#> to / come from the other (double majority). The comparison counts the nodes
#> present in both windows only (`similarity_type` = "partial").
#> Warning: 3 pairs of consecutive windows share no node: their clusters cannot be matched.
#> ℹ Clusters are matched through the nodes they share. In a network of documents
#> (coupling), each node has one date: the windows must overlap (`window_step`
#> smaller than `time_window` in `build_dynamic_networks()`). If windows already
#> overlap, the nodes may have changed completely, or the threshold may leave a
#> window without edges.
networks[[2]]
#> # A tbl_graph: 7 nodes and 6 edges
#> #
#> # An unrooted tree
#> #
#> # Node Data: 7 × 11 (active)
#> source_id source_author source_year source_label source_title source_journal
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 214927 BALL-L 1991 BALL-L-1991 THE GENESIS… "JOURNAL OF M…
#> 2 1111111134 FISCHER-S 1985 FISCHER-S-19… SUPPLY SHOC… "JOURNAL OF M…
#> 3 1184130 GISSER-M 1986 GISSER-M-1986 CRUDE OIL A… "JOURNAL OF M…
#> 4 25481516 HAKES-DR 1988 HAKES-DR-1988 EVIDENCE OF… "REVIEW OF RA…
#> 5 6714008 HELLIWELL-J 1988 HELLIWELL-J-… COMPARATIVE… "JOURNAL OF E…
#> 6 19627977 PARKIN-M 1993 PARKIN-M-1993 INFLATION I… "PRICE STABIL…
#> 7 1111111176 TAYLOR-J 1992 TAYLOR-J-1992 THE GREAT I… "RESERVE BANK…
#> # ℹ 5 more variables: source_type <chr>, time_window <chr>,
#> # cluster_leiden <chr>, size_cluster_leiden <dbl>,
#> # dynamic_cluster_leiden <chr>
#> #
#> # Edge Data: 6 × 11
#> from to weight Source Target cluster_leiden_from cluster_leiden_to
#> <int> <int> <dbl> <chr> <chr> <chr> <chr>
#> 1 6 7 0.0220 1111111176 19627977 01 01
#> 2 3 6 0.0286 1184130 19627977 01 01
#> 3 1 6 0.0807 19627977 214927 01 01
#> # ℹ 3 more rows
#> # ℹ 4 more variables: cluster_leiden <chr>, dynamic_cluster_leiden_from <chr>,
#> # dynamic_cluster_leiden_to <chr>, dynamic_cluster_leiden <chr>
# The same windows, with the Jaccard matching
merge_dynamic_clusters(
networks,
cluster_id = "cluster_leiden",
node_id = "source_id",
method = "jaccard",
threshold_similarity = 0.3,
similarity_type = "partial"
)
#> ℹ Linking clusters across windows with the "jaccard" rule: a cluster inherits
#> the identifier of the past cluster with which its Jaccard index (shared nodes
#> over the union of the two clusters) is the highest, if it is at least 0.3;
#> each identifier passes to one cluster at most. The comparison counts the
#> nodes present in both windows only (`similarity_type` = "partial").
#> ℹ The existing dynamic_cluster_leiden columns are replaced.
#> Warning: 3 pairs of consecutive windows share no node: their clusters cannot be matched.
#> ℹ Clusters are matched through the nodes they share. In a network of documents
#> (coupling), each node has one date: the windows must overlap (`window_step`
#> smaller than `time_window` in `build_dynamic_networks()`). If windows already
#> overlap, the nodes may have changed completely, or the threshold may leave a
#> window without edges.
#> $`1975-1984`
#> # A tbl_graph: 64 nodes and 375 edges
#> #
#> # An undirected simple graph with 1 component
#> #
#> # Node Data: 64 × 11 (active)
#> source_id source_author source_year source_label source_title source_journal
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 37095547 ATESOGLU-H 1980 ATESOGLU-H-… INFLATION A… "JOURNAL OF P…
#> 2 46282251 ATESOGLU-H 1982 ATESOGLU-H-… WAGES AND S… "JOURNAL OF P…
#> 3 42623802 BLAAS-W 1982 BLAAS-W-1982 INSTITUTION… "JOURNAL OF E…
#> 4 5240516 BLINDER-A 1979 BLINDER-A-1… ECONOMIC PO… ""
#> 5 25091445 BLINDER-A 1981 BLINDER-A-1… THE 1971-19… ""
#> 6 31895841 BLINDER-A 1982 BLINDER-A-1… THE ANATOMY… "INFLATION: C…
#> 7 1172921 BRANSON-W 1980 BRANSON-W-1… INTERNATION… ""
#> 8 47749045 BRONFENBRENNE… 1976 BRONFENBREN… ELEMENTS OF… "ZEITSCHRIFT …
#> 9 14490177 BRUNNER-K 1980 BRUNNER-K-1… STAGFLATION… "JOURNAL OF M…
#> 10 6119013 BRUNO-M 1979 BRUNO-M-197… MACRO-ECONO… ""
#> # ℹ 54 more rows
#> # ℹ 5 more variables: source_type <chr>, time_window <chr>,
#> # cluster_leiden <chr>, size_cluster_leiden <dbl>,
#> # dynamic_cluster_leiden <chr>
#> #
#> # Edge Data: 375 × 11
#> from to weight Source Target cluster_leiden_from cluster_leiden_to
#> <int> <int> <dbl> <chr> <chr> <chr> <chr>
#> 1 14 20 0.115 1021902 1111111122 03 03
#> 2 15 20 0.0257 1021902 1111111128 01 03
#> 3 15 21 0.0678 10585974 1111111128 01 02
#> # ℹ 372 more rows
#> # ℹ 4 more variables: cluster_leiden <chr>, dynamic_cluster_leiden_from <chr>,
#> # dynamic_cluster_leiden_to <chr>, dynamic_cluster_leiden <chr>
#>
#> $`1985-1994`
#> # A tbl_graph: 7 nodes and 6 edges
#> #
#> # An unrooted tree
#> #
#> # Node Data: 7 × 11 (active)
#> source_id source_author source_year source_label source_title source_journal
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 214927 BALL-L 1991 BALL-L-1991 THE GENESIS… "JOURNAL OF M…
#> 2 1111111134 FISCHER-S 1985 FISCHER-S-19… SUPPLY SHOC… "JOURNAL OF M…
#> 3 1184130 GISSER-M 1986 GISSER-M-1986 CRUDE OIL A… "JOURNAL OF M…
#> 4 25481516 HAKES-DR 1988 HAKES-DR-1988 EVIDENCE OF… "REVIEW OF RA…
#> 5 6714008 HELLIWELL-J 1988 HELLIWELL-J-… COMPARATIVE… "JOURNAL OF E…
#> 6 19627977 PARKIN-M 1993 PARKIN-M-1993 INFLATION I… "PRICE STABIL…
#> 7 1111111176 TAYLOR-J 1992 TAYLOR-J-1992 THE GREAT I… "RESERVE BANK…
#> # ℹ 5 more variables: source_type <chr>, time_window <chr>,
#> # cluster_leiden <chr>, size_cluster_leiden <dbl>,
#> # dynamic_cluster_leiden <chr>
#> #
#> # Edge Data: 6 × 11
#> from to weight Source Target cluster_leiden_from cluster_leiden_to
#> <int> <int> <dbl> <chr> <chr> <chr> <chr>
#> 1 6 7 0.0220 1111111176 19627977 01 01
#> 2 3 6 0.0286 1184130 19627977 01 01
#> 3 1 6 0.0807 19627977 214927 01 01
#> # ℹ 3 more rows
#> # ℹ 4 more variables: cluster_leiden <chr>, dynamic_cluster_leiden_from <chr>,
#> # dynamic_cluster_leiden_to <chr>, dynamic_cluster_leiden <chr>
#>
#> $`1995-2004`
#> # A tbl_graph: 36 nodes and 379 edges
#> #
#> # An undirected simple graph with 1 component
#> #
#> # Node Data: 36 × 11 (active)
#> source_id source_author source_year source_label source_title source_journal
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 96284971 ALBANESI-S 2003 ALBANESI-S-… EXPECTATION… THE REVIEW OF…
#> 2 2207578 BALL-L 1995 BALL-L-1995a RELATIVE-PR… THE QUARTERLY…
#> 3 10729971 BALL-L 1995 BALL-L-1995b TIME-CONSIS… JOURNAL OF MO…
#> 4 95575910 BARSKY-R 2002 BARSKY-R-20… DO WE REALL… NBER MACROECO…
#> 5 105203318 BARSKY-R 2004 BARSKY-R-20… OIL AND THE… JOURNAL OF EC…
#> 6 43590636 BERNANKE-B 1997 BERNANKE-B-… SYSTEMATIC … BROOKINGS PAP…
#> 7 105203321 BLANCHARD-O 2002 BLANCHARD-O… DO WE REALL… NBER MACROECO…
#> 8 1111111113 BLINDER-A 2002 BLINDER-A-2… DO WE REALL… NBER MACROECO…
#> 9 117262816 CHAPPELL-H 2004 CHAPPELL-H-… DID TIME IN… ECONOMICS & P…
#> 10 60300900 CHARI-V 1998 CHARI-V-1998 EXPECTATION… JOURNAL OF EC…
#> # ℹ 26 more rows
#> # ℹ 5 more variables: source_type <chr>, time_window <chr>,
#> # cluster_leiden <chr>, size_cluster_leiden <dbl>,
#> # dynamic_cluster_leiden <chr>
#> #
#> # Edge Data: 379 × 11
#> from to weight Source Target cluster_leiden_from cluster_leiden_to
#> <int> <int> <dbl> <chr> <chr> <chr> <chr>
#> 1 30 31 0.119 101742279 101742296 03 03
#> 2 28 31 0.0270 101742279 101777013 03 03
#> 3 28 30 0.0783 101742296 101777013 03 03
#> # ℹ 376 more rows
#> # ℹ 4 more variables: cluster_leiden <chr>, dynamic_cluster_leiden_from <chr>,
#> # dynamic_cluster_leiden_to <chr>, dynamic_cluster_leiden <chr>
#>
#> $`2005-2014`
#> # A tbl_graph: 37 nodes and 525 edges
#> #
#> # An undirected simple graph with 1 component
#> #
#> # Node Data: 37 × 11 (active)
#> source_id source_author source_year source_label source_title source_journal
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 140987361 BENATI-L 2011 BENATI-L-20… WOULD THE B… "JOURNAL OF E…
#> 2 113856501 BEYER-A 2007 BEYER-A-2007 NATURAL RAT… "JOURNAL OF E…
#> 3 154773441 BILBIIE-FO 2013 BILBIIE-FO-… ASSET MARKE… "REVIEW OF EC…
#> 4 1111111116 BLINDER-A 2013 BLINDER-A-2… THE SUPPLY-… "THE GREAT IN…
#> 5 1111111117 BORDO-M 2013 BORDO-M-2013 BRETTON WOO… "THE GREAT IN…
#> 6 106371058 BULLARD-J 2005 BULLARD-J-2… DID THE GRE… "REVIEW OF EC…
#> 7 125746912 CANOVA-F 2009 CANOVA-F-20… STRUCTURAL … ""
#> 8 131137084 CARBONI-G 2009 CARBONI-G-2… THE GREAT I… "JOURNAL OF M…
#> 9 6796575 CECCHETTI-S 2007 CECCHETTI-S… UNDERSTANDI… "US MONETARY …
#> 10 106371053 COGLEY-T 2005 COGLEY-T-20… DRIFTS AND … "REVIEW OF EC…
#> # ℹ 27 more rows
#> # ℹ 5 more variables: source_type <chr>, time_window <chr>,
#> # cluster_leiden <chr>, size_cluster_leiden <dbl>,
#> # dynamic_cluster_leiden <chr>
#> #
#> # Edge Data: 525 × 11
#> from to weight Source Target cluster_leiden_from cluster_leiden_to
#> <int> <int> <dbl> <chr> <chr> <chr> <chr>
#> 1 6 10 0.0543 106371053 106371058 04 02
#> 2 10 11 0.150 106371053 106371076 02 02
#> 3 6 11 0.0580 106371058 106371076 04 02
#> # ℹ 522 more rows
#> # ℹ 4 more variables: cluster_leiden <chr>, dynamic_cluster_leiden_from <chr>,
#> # dynamic_cluster_leiden_to <chr>, dynamic_cluster_leiden <chr>
#>
