| Title: | Create Different Types of Bibliometric Networks |
| Version: | 0.2.0 |
| Maintainer: | Aurélien Goutsmedt <agoutsmedt@hotmail.fr> |
| Description: | Functions to find edges for bibliometric networks like bibliographic coupling network, co-citation network and co-authorship network. The weights of network edges can be calculated according to different methods, depending on the type of networks, the type of nodes, and what you want to analyse. These functions are optimized to be be used on large dataset. The package contains functions inspired by: Leydesdorff, Loet and Park, Han Woo (2017) <doi:10.1016/j.joi.2016.11.007>; Perianes-Rodriguez, Antonio, Ludo Waltman, and Nees Jan Van Eck (2016) <doi:10.1016/j.joi.2016.10.006>; Sen, Subir K. and Shymal K. Gan (1983) "A mathematical extension of the idea of bibliographic coupling and its applications", Annals of Library Science and Documentation 30(2); Shen, Si, Zhu, Danhao, Rousseau, Ronald, Su, Xinning and Wang, Dongbo (2019) <doi:10.1016/j.joi.2019.01.012>; Zhao, Dangzhi and Strotmann, Andreas (2008) <doi:10.1002/meet.2008.1450450292>. |
| URL: | https://github.com/agoutsmedt/biblionetwork, https://agoutsmedt.github.io/biblionetwork/ |
| BugReports: | https://github.com/agoutsmedt/biblionetwork/issues |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| LazyData: | true |
| Imports: | cli, data.table (≥ 1.12.0), lifecycle, Matrix (≥ 1.5-0), methods, Rdpack (≥ 0.7), rlang (≥ 1.0.0), stats, utils |
| Depends: | R (≥ 4.1.0) |
| RdMacros: | Rdpack |
| Suggests: | ggplot2, igraph, scico, testthat (≥ 3.0.0), withr |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.1.1 |
| NeedsCompilation: | no |
| Packaged: | 2026-11-04 09:06:14 UTC; agoutsmedt |
| Author: | Aurélien Goutsmedt
|
| Repository: | CRAN |
| Date/Publication: | 2026-11-04 09:20:25 UTC |
biblionetwork: edges of bibliometric networks
Description
Bibliometric networks are built from tables of links between two kinds of
items: documents and the references they cite, authors and the documents
they sign. biblionetwork turns such a table into the edges of a
one-mode network, whose nodes are one of the two kinds of items, with
several ways of weighting the ties. It returns plain tables (data.table),
ready to be turned into a graph with
tidygraph or
igraph, and is the first step of the
networkflow pipeline, which
projects, clusters and draws the networks.
Which function for which question?
| Nodes | Tie | Function |
| citing documents | share references (Kessler 1963) | biblio_coupling(), by default the cosine of coupling_angle() (Sen and Gan 1983) |
| citing documents | share rare references | coupling_strength(), coupling_similarity() (Shen et al. 2019) |
| citing documents | other classic normalisations | coupling_jaccard() (Sen and Gan 1983), coupling_vladutz() (Vladutz and Cook 1984) |
| citing documents | cite different but related references (similar titles) | coupling_descriptive() (Liu 2017) |
| cited references | are cited together (Small 1973) | biblio_cocitation() |
| authors, institutions, countries | co-sign documents | coauth_network() |
| entities (authors, journals...) | their documents cite the same references, or are cited together | entity_network(): not a new measure, the aggregation of the measures above at the level of entities
|
The measures of coupling do not give the same weights: compute_couplings()
computes several of them at once, and summarise_weights(),
correlate_weights(), overlap_top_weights() and plot_weights() compare
the distributions and the rankings of their weights.
Coupling ties are fixed when documents are published, so they suit the comparison of successive time windows; co-citation ties depend on later citations and describe the reception of the cited documents. The article How to use biblionetwork illustrates all the functions on the data of the package (the literature explaining the US stagflation of the 1970s, (Goutsmedt 2021)).
Conventions shared by all the functions
the input is a table of links with the names of two columns; it is never modified;
networks are undirected: each pair of nodes appears once, in the columns
SourceandTarget;fromandtoare copies, because tidygraph modifies them;duplicated rows are counted once; rows with missing identifiers are dropped with a warning;
if no pair of nodes is linked, a warning explains why (nothing shared, or a
weight_thresholdthat is too high) and a table with zero rows and the usual columns is returned;all the measures are computed from the whole table: the weights depend on the corpus.
Author(s)
Maintainer: Aurélien Goutsmedt agoutsmedt@hotmail.fr (ORCID)
Authors:
Aurélien Goutsmedt agoutsmedt@hotmail.fr (ORCID)
François Claveau (ORCID)
Alexandre Truc (ORCID)
References
Goutsmedt A (2021).
“From the Stagflation to the Great Inflation: Explaining the US Economy of the 1970s.”
Revue d'Economie Politique, Forthcoming.
https://aurelien-goutsmedt.com/media/pdf/stagflation-great-inflation.pdf.
Kessler MM (1963).
“Bibliographic Coupling between Scientific Papers.”
American Documentation, 14(1), 10–25.
doi:10.1002/asi.5090140103.
Liu R (2017).
“A New Bibliographic Coupling Measure with Descriptive Capability.”
Scientometrics, 110(2), 915–935.
doi:10.1007/s11192-016-2196-7.
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
Small H (1973).
“Co-Citation in the Scientific Literature: A New Measure of the Relationship between Two Documents.”
Journal of the American Society for Information Science, 24(4), 265–269.
doi:10.1002/asi.4630240406.
Vladutz G, Cook J (1984).
“Bibliographic Coupling and Subject Relatedness.”
Proceedings of the American Society for Information Science, 21, 204–207.
See Also
Useful links:
Report bugs at https://github.com/agoutsmedt/biblionetwork/issues
List of Authors of the Articles and Books Explaining the 1970s US Stagflation.
Description
A dataset associating the books and academic articles endeavouring to explain
the US stagflation and their authors (Nodes_stagflation just takes the first author;
here is the complete list of authors per document).
Usage
Authors_stagflation
Format
A data frame with 558 rows and 7 variables:
- ItemID_Ref
Identifier of the document published by the author
- Author
Author of the document
- Order
Use this as a label for nodes
Source
Goutsmedt A. (2020) “From Stagflation to the Great Inflation: Explaining the 1970s US Economic Situation”. Revue d’Economie Politique, Forthcoming 2021.
Articles and Books Explaining the 1970s US Stagflation.
Description
A dataset containing the books and academic articles endeavouring to explain what happened in the US economy in the 1970s, as well as all the articles and books cited at least twice by the first set of articles and books (on the stagflation).
Usage
Nodes_stagflation
Format
A data frame with 558 rows and 7 variables:
- ItemID_Ref
Identifier of the document
- Author
Author of the document
- Author_date
Use this as a label for nodes
- Year
Year of publication of the document
- Title
Title of the document
- Journal
Journal of publication of the document (if an article)
- Type
If "Stagflation", the document is listed as an explanation of the US stagflation. If "Non-Stagflation", the document is cited by a document explaining the stagflation
Source
Goutsmedt A. (2020) “From Stagflation to the Great Inflation: Explaining the 1970s US Economic Situation”. Revue d’Economie Politique, Forthcoming 2021.
Articles and Books Explaining the 1970s US Stagflation.
Description
A dataset containing all the articles and books cited by the books and academic articles endeavouring to explain what happened in the US economy in the 1970s.
Usage
Ref_stagflation
Format
A data frame with 4416 rows and 6 variables:
- Citing_ItemID_Ref
Identifier of the citing document
- ItemID_Ref
Identifier of the cited document
- Author
Author of the cited document
- Year
Year of publication of the cited document
- Title
Title of the cited document
- Journal
Journal of publication of the cited document (if an article)
Source
Goutsmedt A. (2020) “From Stagflation to the Great Inflation: Explaining the 1970s US Economic Situation”. Revue d’Economie Politique, Forthcoming 2021.
Co-citation edges, with the same weights as the coupling measures
Description
Builds the edges of a co-citation network from a table of direct
citations (one row per citing document and cited reference). Two
references are co-cited when at least one document cites both of them
(Small 1973). By default the weight is the
co-citation angle (Sen and Gan 1983): the number of
documents citing both references, divided by the geometric mean of the
numbers of citations received by each of them. With method, the
co-citation can also be weighted like the coupling measures
(coupling_strength(), coupling_similarity(), coupling_jaccard(),
coupling_vladutz()): see the section on the idf weights below.
Usage
biblio_cocitation(
dt,
source,
ref,
normalized_weight_only = TRUE,
weight_threshold = 1,
output_in_character = TRUE,
method = c("angle", "strength", "similarity", "jaccard", "vladutz")
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references: they are the nodes of the co-citation network. |
normalized_weight_only |
Logical. If |
weight_threshold |
Number. The minimum number of documents that must cite two references together for them to be linked (1 by default). |
output_in_character |
Logical. If |
method |
The weight: |
Details
Write C(A) for the set of documents citing reference A. The
weight of the tie between references A and B with the default
method = "angle" is
w_{AB} = \frac{|C(A) \cap C(B)|}{\sqrt{|C(A)| \, |C(B)|}}
The numerator is the number of documents citing both references (returned
as nb_shared_citations when normalized_weight_only = FALSE). The
other methods are those of the coupling functions, applied to the
references as nodes: see the documentation of each, replacing "document"
by "reference" and "reference" by "citing document".
Computing choices:
-
|C(A)|is the number of citations received in the whole table, including from documents that cite only one reference; documents citing a single reference cannot co-cite anything and are ignored in the numerator;
duplicated rows are counted once, and rows with a missing identifier are dropped with a warning;
the table of the user is not modified;
if no pair of references is co-cited (or none reaches
weight_threshold), a zero-row table is returned with a warning explaining why.
Memory and speed: the pairs are computed with sparse matrices, as in
coupling_angle(); a few documents with extremely long bibliographies
still create many pairs. Consider removing them first.
Value
A data.table with one row per pair of references: the
identifiers in from and to (if output_in_character = TRUE), the
weight and, if normalized_weight_only = FALSE,
nb_shared_citations. The original identifiers are kept in Source
and Target. Each pair appears once, with Source < Target.
Why use it in research
Where bibliographic coupling looks at what documents use, co-citation
looks at how the community perceives cited documents: references that
are regularly cited together are considered by citing authors as belonging
to the same body of work. Co-citation networks are the classic tool to
map the intellectual base of a field (schools, paradigms, canonical
references) and to identify the key texts of each cluster
(Boyack et al. 2005; Boyack and Klavans 2010; Yan and Ding 2012). Unlike
coupling, a co-citation network is not fixed at the date of publication
of the cited documents: it depends on later citations, and thus changes
as the corpus of citing documents grows. This is a feature if you want to
study how the reception of texts evolves, but it must be kept in mind
when comparing time windows. A reference that is rarely cited has a very
uncertain position, hence the interest of weight_threshold.
Intuition
Imagine that each citing document is a reading list. Two references that
appear together on many lists are probably about related things. The
weight with method = "angle" asks: among all the lists where one of
the two references appears, how often is the other one there too? A
reference cited a thousand times appears on many lists by default, so it
must be seen with another reference much more often to be considered
close to it: that is what the division by the number of citations does.
Weighting the co-citing documents (the idf methods)
The idf measures of the coupling functions give more weight to a
rare shared item. In coupling, the shared items are references, and a
reference cited by few documents is rare. Co-citation is the mirror
image (Rousseau 2010): the shared items are the
citing documents, and a citing document is "rare" when it cites few
references. The intuition is again about reading lists: a document that
cites only 8 references and puts A and B among them tells much more
about the closeness of A and B than a review that cites 300 references
and puts A and B among them by completeness. With method = "strength"
(and "similarity"), the co-citation of A and B by a document d is
weighted by \log(M / L_d), with M the number of references in
the table and L_d the number of references of d. This is a
direct transposition of the formulas of coupling_strength() and
coupling_similarity() (swapping the two columns of the table): it is
not a measure proposed in the literature as such, so compare it with the
default on your corpus (compute_couplings() with
network = "cocitation").
References
Boyack KW, Klavans R (2010).
“Co-Citation Analysis, Bibliographic Coupling, and Direct Citation: Which Citation Approach Represents the Research Front Most Accurately?”
Journal of the American Society for Information Science and Technology, 61(12), 2389–2404.
doi:10.1002/asi.21419.
Boyack KW, Klavans R, Börner K (2005).
“Mapping the Backbone of Science.”
Scientometrics, 64(3), 351–374.
doi:10.1007/s11192-005-0255-6.
Rousseau R (2010).
“Bibliographic Coupling and Co-Citation as Dual Notions.”
In The Janus Faced Scholar: A Festschrift in Honour of Peter Ingwersen, 167–173.
Royal School of Library and Information Science, Copenhagen.
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Small H (1973).
“Co-Citation in the Scientific Literature: A New Measure of the Relationship between Two Documents.”
Journal of the American Society for Information Science, 24(4), 265–269.
doi:10.1002/asi.4630240406.
Yan E, Ding Y (2012).
“Scholarly Network Similarities: How Bibliographic Coupling Networks, Citation Networks, Cocitation Networks, Topical Networks, Coauthorship Networks, and Coword Networks Relate to Each Other.”
Journal of the American Society for Information Science and Technology, 63(7), 1313–1326.
doi:10.1002/asi.22680.
See Also
Other co-citation and co-authorship measures:
coauth_network()
Examples
library(biblionetwork)
# Co-citation network of the references of the stagflation corpus,
# keeping the pairs co-cited at least three times
edges <- biblio_cocitation(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
weight_threshold = 3)
head(edges)
# The same pairs, weighted by the specificity of the co-citing documents
head(biblio_cocitation(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
weight_threshold = 3, method = "strength"))
Bibliographic coupling edges, with the weighting method of your choice
Description
The general entry point to bibliographic coupling. From a table of direct
citations (one row per citing document and cited reference), it returns the
edges of the network linking the documents that share references
(Kessler 1963), weighted by the method you
choose. It is a thin wrapper: every method is also available as a
function of its own, which documents the formula and the reasons to
choose it.
method | Function | Weight |
"angle" (default) | coupling_angle() | cosine of the bibliographies (Sen and Gan 1983) |
"strength" | coupling_strength() | shared references weighted by their rarity (Shen et al. 2019) |
"similarity" | coupling_similarity() | idf-weighted cosine (Shen et al. 2019) |
"jaccard" | coupling_jaccard() | shared references over the union of the bibliographies (Sen and Gan 1983) |
"vladutz" | coupling_vladutz() | Vladutz and Cook formula (Vladutz and Cook 1984) |
In versions up to 0.1.1, biblio_coupling() was what is now
coupling_angle(): calls that leave method to its default give the same
result. To compare several methods at once on the same corpus, use
compute_couplings(); to couple authors, journals or institutions rather
than documents, use entity_network(); to link cited references, use
biblio_cocitation().
Usage
biblio_coupling(
dt,
source,
ref,
method = c("angle", "strength", "similarity", "jaccard", "vladutz"),
normalized_weight_only = TRUE,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
method |
The weighting method, one of |
normalized_weight_only |
Logical. If |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default: any shared reference creates a tie). A threshold of 2 or 3 is common in large corpora, where sharing a single reference is weak evidence of proximity and produces very dense networks. It applies to the number of shared references, not to the normalised weight. |
output_in_character |
Logical. If |
Details
Value
A data.table with one row per pair of documents sharing at least
weight_threshold references: Source and Target (identifiers, with
Source < Target), from and to (the same, as characters, if
output_in_character = TRUE), the weight and, if
normalized_weight_only = FALSE, nb_shared_references. Whatever the
method, the weights of different methods do not have the same scale: see
compute_couplings() to compare them.
References
Kessler MM (1963).
“Bibliographic Coupling between Scientific Papers.”
American Documentation, 14(1), 10–25.
doi:10.1002/asi.5090140103.
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
Vladutz G, Cook J (1984).
“Bibliographic Coupling and Subject Relatedness.”
Proceedings of the American Society for Information Science, 21, 204–207.
See Also
Other coupling measures:
coupling_angle(),
coupling_descriptive(),
coupling_jaccard(),
coupling_similarity(),
coupling_strength(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
# The default is the coupling angle...
head(biblio_coupling(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
weight_threshold = 3))
# ...and the method changes the weights, not the pairs of documents
head(biblio_coupling(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
method = "strength",
weight_threshold = 3))
Co-authorship edges, with full or fractional counting
Description
Builds the edges of a co-authorship network from a table with one row per author (or institution, or country) and document. Two authors are linked when they have co-signed documents. The weight of the tie can count each collaboration fully, or share it between the pairs of co-authors of a document (fractional counting), following (Perianes-Rodriguez et al. 2016; Leydesdorff and Park 2017-02), and can be normalised by the productivity of the two authors with a cosine.
Usage
coauth_network(
dt,
authors,
articles,
method = c("full_counting", "fractional_counting", "fractional_counting_refined"),
cosine_normalized = FALSE
)
Arguments
dt |
A data frame or a |
authors |
Character scalar. The column of the authors (or institutions, or countries), the nodes of the network. |
articles |
Character scalar. The column of the documents. |
method |
|
cosine_normalized |
Logical. If |
Details
Write a_{ik} = 1 if author i signed document k, and
n_k = \sum_i a_{ik} for its number of authors. The weight of the tie
between i and j is, according to method:
-
"full_counting": the number of documents they co-signed,w_{ij} = \sum_{k} a_{ik} a_{jk} -
"fractional_counting"(Perianes-Rodriguez et al. 2016): each document gives1/(n_k - 1)to each pair,w_{ij} = \sum_{k} \frac{a_{ik} a_{jk}}{n_k - 1}so that the weights of the ties of an author in a document sum to 1;
-
"fractional_counting_refined", inspired by (Leydesdorff and Park 2017-02): each document gives2 / (n_k (n_k - 1))to each pair,w_{ij} = \sum_{k} \frac{2 \, a_{ik} a_{jk}}{n_k (n_k - 1)}so that each document has a total weight of 1 in the network: the sum of all the weights equals the number of (multi-authored) documents.
If cosine_normalized = TRUE, the weight is divided by
\sqrt{P_i P_j}, with P_i the number of co-authored documents
of author i (documents with a single author are ignored in the
whole function, since they create no tie).
Duplicated rows are counted once, rows with a missing identifier are dropped with a warning, the table of the user is not modified, and a zero-row table is returned, with a warning, if nobody co-authored a document.
Value
A data.table with one row per pair of authors: from and to
(copies of Source and Target, with the type of the authors
column), the weight, and the original identifiers in Source and
Target. Each pair appears once, with Source > Target (the orientation of
the previous versions of the package).
Why use it in research
Co-authorship networks describe the social structure of a research community: who collaborates with whom, the existence of collaborative cliques, the central or bridging positions. The way collaborations are counted changes the picture. With full counting, a document signed by ten authors creates 45 ties of weight 1 and weighs much more in the network than a document signed by two authors; fractional counting corrects this by giving a document a total weight that does not depend on its number of authors. Normalising by productivity prevents very prolific authors from being linked to everybody. Perianes-Rodriguez et al. (Perianes-Rodriguez et al. 2016) compare full and fractional counting for bibliometric networks: read it before choosing. The nodes can be authors, institutions or countries, the latter being the basis of studies of international collaboration.
Intuition
Think of each document as a pie of value 1 to share among the pairs of its authors. With full counting, every pair of co-authors receives a full pie: a document with ten authors distributes 45 pies, a document with two authors distributes one. With fractional counting, a document always distributes the same total (one pie in the refined version, or one pie per author in the other), so that large collaborations do not dominate. The cosine then asks whether two authors collaborate much relative to how much each of them collaborates in general.
References
Leydesdorff L, Park HW (2017-02).
“Full and Fractional Counting in Bibliometric Networks.”
Journal of Informetrics, 11(1), 117–120.
ISSN 17511577.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716303133.
Perianes-Rodriguez A, Waltman L, Van Eck NJ (2016).
“Constructing Bibliometric Networks: A Comparison between Full and Fractional Counting.”
Journal of Informetrics, 10(4), 1178–1195.
https://www.sciencedirect.com/science/article/pii/S1751157716302036?casa_token=AtzjmZ-1QmYAAAAA:2mlBPZsjGUleYi9mnybHODFw2RmMh3GHvRAuMYXygRm63cQOv07M4ixbAmJXuGq71tx2ug29baTp.
See Also
Other co-citation and co-authorship measures:
biblio_cocitation()
Examples
library(biblionetwork)
coauth_network(Authors_stagflation,
authors = "Author",
articles = "ItemID_Ref",
method = "fractional_counting")
# Toy example: three authors sign document 1, two sign document 2.
# With fractional counting, a-b gets 1/2 + 1/1 = 1.5
toy <- data.frame(author = c("a", "b", "c", "a", "b"),
paper = c(1, 1, 1, 2, 2))
coauth_network(toy, authors = "author", articles = "paper",
method = "fractional_counting")
Compute several coupling (or co-citation) measures at once
Description
Computes several measures of bibliographic coupling (or of co-citation)
on the same table of citations and returns a named list of edge tables,
ready for summarise_weights(), correlate_weights(),
overlap_top_weights(), merge_weights() and plot_weights(). The
costly step (finding all the pairs of nodes that share a reference) is
done only once, so computing the five measures costs little more than
computing one.
Usage
compute_couplings(
dt,
source,
ref,
methods = c("angle", "strength", "similarity", "jaccard", "vladutz"),
weight_threshold = 1,
network = c("coupling", "cocitation"),
title = NULL,
descriptive_args = list()
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
methods |
Character vector, among |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default: any shared reference creates a tie). A threshold of 2 or 3 is common in large corpora, where sharing a single reference is weak evidence of proximity and produces very dense networks. It applies to the number of shared references, not to the normalised weight. |
network |
|
title |
Character scalar. The column with the title of the cited
references, needed (only) for |
descriptive_args |
A list of further arguments for
|
Details
The five measures that start from the shared references are computed on
the same pairs of nodes (those sharing at least weight_threshold
references), so that their weights can be compared pair by pair.
"descriptive" (the DescriptiveBC measure of
(Liu 2017)) is different in two ways. It
couples documents that cite different but related references, so its
pairs are not the same ones: any pair of documents with similar titles of
references is concerned, whatever the number of shared references (the
weight_threshold does not apply to it). And its cost grows with the
square of the number of documents: the function informs you when you
ask for it, and you should give targets or work on a time window for a
large corpus. merge_weights() puts the tables side by side, with NA
for the pairs a measure does not have.
Value
A named list with one data.table per method, each with columns
Source, Target and weight. The tables of the five measures
describe the same pairs of nodes (those sharing at least
weight_threshold references, or co-cited at least weight_threshold
times), in the same order. The table of "descriptive" has its own pairs.
Why use it in research
The choice of a measure is a modelling choice, not a technical detail: it determines which pairs of documents look close, and thus the communities found. (Shen et al. 2019) show on one corpus that the measures can be very close (coupling angle and similarity) or quite different (Vladutz-Cook and the others). Whether it matters for your corpus can only be checked on your corpus: compute the measures with this function, and compare the distributions and the rankings of the weights. The article comparing the measures does it on the stagflation corpus.
References
Liu R (2017).
“A New Bibliographic Coupling Measure with Descriptive Capability.”
Scientometrics, 110(2), 915–935.
doi:10.1007/s11192-016-2196-7.
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other tools to compare coupling measures:
correlate_weights(),
merge_weights(),
overlap_top_weights(),
plot_weights(),
summarise_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
weight_threshold = 2)
names(edges)
summarise_weights(edges)
correlate_weights(edges)
# The titles-based measure is not computed by default; it needs the titles of the references
toy <- data.frame(
doc = c("a", "a", "b", "b"),
ref = c("r1", "r2", "r1", "r3"),
title = c("inflation expectations", "oil supply shocks",
"inflation expectations", "supply shocks prices")
)
compute_couplings(toy, "doc", "ref", methods = c("angle", "descriptive"), title = "title")
Correlate the weights of several measures
Description
Computes the correlation between the weights of each pair of measures, over the pairs of nodes present in all the tables, as (Shen et al. 2019) do with Pearson correlations. The default is the Spearman rank correlation, which compares the rankings of the pairs and does not depend on the scale of the weights: it is the relevant one when the weights are only used to order or filter edges, as in most community detection settings. Pearson correlations (the paper's choice) are sensitive to the scale and to extreme values, and thus differ much more between a bounded cosine and an unbounded strength.
Usage
correlate_weights(edges, method = c("spearman", "pearson", "kendall"))
Arguments
edges |
A named list of at least two edge tables, for instance from
|
method |
|
Details
Value
A correlation matrix, with the number of pairs of nodes used in
the attribute "n_pairs".
References
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019). “A Refined Method for Computing Bibliographic Coupling Strengths.” Journal of Informetrics, 13(2), 605–615. https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other tools to compare coupling measures:
compute_couplings(),
merge_weights(),
overlap_top_weights(),
plot_weights(),
summarise_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
weight_threshold = 2)
correlate_weights(edges)
correlate_weights(edges, method = "pearson")
Bibliographic coupling edges, weighted by the coupling angle
Description
Builds the edges of a bibliographic coupling network from a table of direct citations (one row per citing document and cited reference). Two documents are coupled when their bibliographies overlap (Kessler 1963), and the weight of the tie is the coupling angle (Sen and Gan 1983): the number of shared references divided by the geometric mean of the lengths of the two bibliographies (a cosine).
Usage
coupling_angle(
dt,
source,
ref,
normalized_weight_only = TRUE,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
normalized_weight_only |
Logical. If |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default: any shared reference creates a tie). A threshold of 2 or 3 is common in large corpora, where sharing a single reference is weak evidence of proximity and produces very dense networks. It applies to the number of shared references, not to the normalised weight. |
output_in_character |
Logical. If |
Details
Write R(A) for the set of references of document A, and
L(A) = |R(A)| for the length of its bibliography. The weight of the
tie between A and B is
w_{AB} = \frac{|R(A) \cap R(B)|}{\sqrt{L(A) \, L(B)}}
The numerator is the number of shared references (returned as
nb_shared_references when normalized_weight_only = FALSE). Dividing by
\sqrt{L(A) L(B)} avoids giving too much importance to documents with
a long bibliography, such as literature reviews. The weight lies between 0
and 1, and is 1 only if the two bibliographies are identical.
The function applies the following rules, which matter for the interpretation of the result:
duplicated rows are counted once, and a document citing itself is ignored;
-
L(A)counts all the references ofA, including those cited by no other document of the table. Such references cannot create a tie but they lengthen the bibliography, and so lower the weights ofA; rows with a missing identifier are dropped, with a warning;
the table of the user is not modified;
if no reference is shared by two documents (or if no pair reaches
weight_threshold), a zero-row table is returned, with the usual columns, and a warning that says why.
The function is written with data.table and is fast, but it first lists
every pair of documents citing a same reference: a reference cited by
n documents creates n (n - 1) / 2 pairs. Very popular
references (a classic cited by tens of thousands of documents) may
therefore exhaust the memory on a large corpus. Split the corpus (by time
window, for instance), or remove the most cited references, before
calling the function.
The function is general: it only needs two columns of identifiers. With
source the articles and ref the words of their titles, it builds a
title co-occurrence network; with source the cited documents and ref
the citing ones, a co-citation network (but see biblio_cocitation()).
Value
A data.table with one row per pair of documents sharing at least
weight_threshold references: the identifiers in from and to (if
output_in_character = TRUE), the weight (coupling angle) and,
if normalized_weight_only = FALSE, nb_shared_references. The
original identifiers are kept in Source and Target (from and to
are modified by tidygraph when a graph is created). The network is
undirected: each pair appears once, with Source < Target.
Why use it in research
Documents that cite the same references rely on the same literature: they are likely to address related questions, with related tools. Bibliographic coupling is therefore a standard way of mapping the research fronts of a field, and to group documents into specialities or schools with a community detection algorithm (Boyack et al. 2005; Boyack and Klavans 2010; Yan and Ding 2012). Two properties make it convenient for the history and sociology of science:
the links are fixed when a document is published, since they depend only on its own bibliography. A network built for 1970-1979 does not change when later documents are added, which allows comparing successive time windows (a dynamic analysis);
it covers all the documents of the corpus, even uncited ones, as long as their references are recorded.
Its limit is the quality of the reference lists: documents without
recorded references cannot be linked. Compare with the
co-citation approach, which links cited documents
and changes as new citations accumulate, and with the measures that weight
the shared references (coupling_strength(), coupling_similarity()).
Intuition
Picture each bibliography as a shopping list. Two lists that contain many of the same items are probably written by people who shop for the same meal. But a very long list contains many items by sheer size, and would look similar to everybody: the weight therefore compares the shared items with the geometric mean of the lengths of the two lists. Geometrically, each document is an arrow in a space with one axis per reference, pointing along the axes of the references it cites; the weight is the cosine of the angle between two arrows (hence "coupling angle"): 1 for identical bibliographies (same direction), 0 for bibliographies with nothing in common (perpendicular).
References
Boyack KW, Klavans R (2010).
“Co-Citation Analysis, Bibliographic Coupling, and Direct Citation: Which Citation Approach Represents the Research Front Most Accurately?”
Journal of the American Society for Information Science and Technology, 61(12), 2389–2404.
doi:10.1002/asi.21419.
Boyack KW, Klavans R, Börner K (2005).
“Mapping the Backbone of Science.”
Scientometrics, 64(3), 351–374.
doi:10.1007/s11192-005-0255-6.
Kessler MM (1963).
“Bibliographic Coupling between Scientific Papers.”
American Documentation, 14(1), 10–25.
doi:10.1002/asi.5090140103.
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Yan E, Ding Y (2012).
“Scholarly Network Similarities: How Bibliographic Coupling Networks, Citation Networks, Cocitation Networks, Topical Networks, Coauthorship Networks, and Coword Networks Relate to Each Other.”
Journal of the American Society for Information Science and Technology, 63(7), 1313–1326.
doi:10.1002/asi.22680.
See Also
biblio_coupling(), which gives access to this measure and to the
other methods through its method argument.
Other coupling measures:
biblio_coupling(),
coupling_descriptive(),
coupling_jaccard(),
coupling_similarity(),
coupling_strength(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
# Edges between the documents explaining the 1970s stagflation, keeping
# the pairs that share at least three references
edges <- coupling_angle(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
weight_threshold = 3)
head(edges)
# A tiny example that can be checked by hand: d1 and d2 share two of
# their (respectively 3 and 2) references, so the weight is 2 / sqrt(3 * 2)
toy <- data.frame(doc = c("d1", "d1", "d1", "d2", "d2"),
ref = c("r1", "r2", "r3", "r1", "r2"))
coupling_angle(toy, source = "doc", ref = "ref", normalized_weight_only = FALSE)
Bibliographic coupling edges using the titles of the references (DescriptiveBC)
Description
The DescriptiveBC measure of (Liu 2017). In the standard bibliographic coupling, two references are either the same or completely different. Here two different references can be partly similar if their titles share words, so that two documents can be coupled even if they cite few identical references.
Usage
coupling_descriptive(
dt,
source,
ref,
title,
targets = NULL,
min_weight = 0,
output_in_character = TRUE,
stopwords = NULL,
max_documents = 5000
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
title |
Character scalar. The column with the title of the cited reference (one title per reference). |
targets |
Optional vector of identifiers of documents (values of
|
min_weight |
Number. Only pairs with a weight strictly above it are
returned (0 by default: all the pairs with some similarity). There is no
|
output_in_character |
Logical. If |
stopwords |
Character vector of words to ignore in the titles
( |
max_documents |
Number. The maximum number of documents allowed
without |
Details
The similarity of two references r_1 and r_2 is 1 if they are
the same reference, and otherwise the Jaccard index of the sets of terms
of their titles,
\mathrm{Sim}(r_1, r_2) = |T(r_1) \cap T(r_2)| / |T(r_1) \cup T(r_2)|.
The weight between documents A and B, with reference sets
R_A and R_B, is
w_{AB} = \frac{\sum_{r \in R_A} \max_{r' \in R_B} \mathrm{Sim}(r, r') + \sum_{r' \in R_B} \max_{r \in R_A} \mathrm{Sim}(r, r')}{|R_A| + |R_B|}
(Eq. 5 of the paper). It lies between 0 and 1. If no two references are
similar except identical ones, it is 2 |R_A \cap R_B| / (|R_A| + |R_B|),
the Dice coefficient of the bibliographies.
Terms are the words of the titles, in lower case, without the
stopwords that you give (for instance stopwords::stopwords("en")):
without them, words such as "the" or "of" create similarities between
unrelated titles. The paper does not specify other pre-processing (no
stemming here). A reference without title is only similar to itself. If a
reference has several titles in the table, the first is used, with a
warning.
Computing cost. Unlike the other coupling measures, there is no
natural set of candidate pairs: two documents sharing no reference can be
similar through the words of the titles. All the pairs of documents are
therefore potentially concerned, and the cost grows with the square of the
number of documents. The function (i) computes the similarity of the pairs
of references sharing a term with sparse matrices, and (ii) for each
target document, finds the best matches of its references. With a very
large corpus, give the targets (the documents for which you want the
neighbours, as in the paper, where each article is compared with
candidates) or restrict the corpus by time windows. Removing stop words
reduces the number of similar references a lot. By default, more than
max_documents documents without targets is an error.
Value
A data.table with one row per pair of documents with a weight
above min_weight: from and to (character if
output_in_character = TRUE), the weight, and the original
identifiers in Source and Target (Source < Target).
Why use it in research
Two papers on the same question often cite different but related works
(the same idea in a working paper and in a journal article, two papers on
the same model). Classical coupling misses them, and the sparsity of
citations makes it dominated by a few shared references
(Liu 2017). Using the words of the titles of the
references recovers part of this relatedness. It also lets you say why
two documents are related: see descriptive_terms(). The price is a
dependence on the quality of the titles (language, abbreviations, missing
titles) and a much higher computing cost, since almost any two documents
can have some similarity (see below). Liu evaluates the measure on
biomedical articles, against expert judgements of relatedness: check on
your own field that title words are informative (in the social sciences
titles are often metaphorical).
Intuition
Imagine that you compare two reading lists, and that you are allowed to match each book of the first list with its closest book in the second: the same book is a perfect match (1), a book whose title shares half of its words is a half match, unrelated titles do not match (0). The measure is the average quality of the best matches, in both directions.
References
Liu R (2017). “A New Bibliographic Coupling Measure with Descriptive Capability.” Scientometrics, 110(2), 915–935. doi:10.1007/s11192-016-2196-7.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_jaccard(),
coupling_similarity(),
coupling_strength(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
# a and b cite different references, with partly shared title words
toy <- data.frame(
doc = c("a", "a", "b", "b"),
ref = c("r1", "r2", "r1", "r3"),
title = c("inflation expectations", "oil supply shocks",
"inflation expectations", "supply shocks prices")
)
# 1 for r1; r2 and r3 share 2 of 4 terms: w = (1 + 0.5 + 1 + 0.5) / 4
coupling_descriptive(toy, source = "doc", ref = "ref", title = "title")
Coupling edges between entities (deprecated)
Description
coupling_entity() was renamed entity_network(), because it is not a
measure of coupling of its own but the aggregation of the coupling (or
co-citation) measures at the level of entities. It is kept as a wrapper,
that accepts the former names of the methods ("coupling_strength",
"coupling_angle", "coupling_similarity"), and will be removed in a
future version.
Usage
coupling_entity(
dt,
source,
ref,
entity,
weight_threshold = 1,
output_in_character = FALSE,
method = c("coupling_strength", "coupling_angle", "coupling_similarity")
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents.
Needed to count the documents, not to define the nodes (except for
|
ref |
Character scalar. The column of the cited references. |
entity |
Character scalar. The column of the entities that are the
nodes of the network (authors, journals, institutions...). With
|
weight_threshold |
Number. The minimum number of shared references for two entities to be linked (1 by default). With large entities such as journals, a higher value is advisable. |
output_in_character |
Logical. If |
method |
|
Details
Value
See entity_network().
Bibliographic coupling edges, weighted by the relative coupling strength (Jaccard)
Description
The relative bibliographic coupling strength of
(Sen and Gan 1983): the number of references shared by
two documents divided by the number of references in the union of their
bibliographies. It is a Jaccard index, as noted by
(Shen et al. 2019) (who credit Egghe and Rousseau,
1990). It is the other classic normalisation of the number of shared
references, next to the cosine of coupling_angle().
Usage
coupling_jaccard(
dt,
source,
ref,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default: any shared reference creates a tie). A threshold of 2 or 3 is common in large corpora, where sharing a single reference is weak evidence of proximity and produces very dense networks. It applies to the number of shared references, not to the normalised weight. |
output_in_character |
Logical. If |
Details
With R(A) the references of A and L(A) = |R(A)|,
w_{AB} = \frac{|R(A) \cap R(B)|}{L(A) + L(B) - |R(A) \cap R(B)|} = \frac{|R(A) \cap R(B)|}{|R(A) \cup R(B)|}
Computing choices: see coupling_angle(). L(A) counts all the
references of A, including those cited by no other document.
Value
A data.table with one row per pair of documents sharing at
least weight_threshold references: from and to (character if
output_in_character = TRUE), the weight (between 0 and 1) and the
original identifiers in Source and Target. Each pair appears once,
with Source < Target.
Why use it in research
Like the coupling angle, it corrects for the length of the bibliographies,
but differently: the cosine divides by the geometric mean of the lengths,
the Jaccard index by the size of the union. The Jaccard index is never
above the cosine, and penalises more strongly the pairs of documents with
bibliographies of very different lengths. Both are bounded between 0 and 1 and give very similar
rankings in practice ((Shen et al. 2019) report a
Pearson correlation of 0.956 between the two on their corpus): compare
them on yours with correlate_weights().
Intuition
Take all the references cited by at least one of the two documents (their
union): the weight is the share of them that both documents cite. It is
the answer to "of everything these two documents read, how much did they
read in common?". If one document cites 5 references, all cited by the other
one, which cites 50, the cosine is 5/\sqrt{250} \approx 0.32 and the
Jaccard index 5/50 = 0.1: the Jaccard index sees that the second
document reads much more than the first.
References
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_descriptive(),
coupling_similarity(),
coupling_strength(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
# d1 = {r1, r2, r3} and d2 = {r1, r2} share 2 references out of 3
toy <- data.frame(doc = c("d1", "d1", "d1", "d2", "d2"),
ref = c("r1", "r2", "r3", "r1", "r2"))
coupling_jaccard(toy, source = "doc", ref = "ref")
Bibliographic coupling edges, weighted by the idf-weighted cosine (SIM)
Description
The cosine counterpart of coupling_strength(). It is the similarity
measure SIM_{CS} of (Shen et al. 2019), which
generalises the coupling angle of coupling_angle()
(Sen and Gan 1983): instead of describing a document by
a 0/1 vector over references, it uses a vector whose components are the
(square roots of the) idf weights of the references, and takes the cosine
of the vectors of two documents. The weight is therefore bounded between
0 and 1.
Usage
coupling_similarity(
dt,
source,
ref,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default). It applies to the number of shared references, not to the weight. |
output_in_character |
Logical. If |
Details
Write N for the number of citing documents in the table, f_j
for the number of documents citing reference j, and
\mathrm{idf}_j = \log(N / f_j). The vector of document A has
one component per reference of A, equal to
\sqrt{\mathrm{idf}_j}. The cosine of two such vectors is
w_{AB} = \frac{\sum_{j \in R(A) \cap R(B)} \mathrm{idf}_j}{\sqrt{S(A) \, S(B)}}, \qquad S(A) = \sum_{j \in R(A)} \mathrm{idf}_j
where S(A) sums the idf of all the references of A, shared
or not (the squared norm of its vector). The numerator is the numerator of
the coupling strength. The weight does not depend on the base of the
logarithm (the natural logarithm is used), since the base multiplies
numerator and denominator by the same constant.
References cited once have \mathrm{idf}_j = \log N, the highest
value: they cannot create a tie but they increase S(A), as the
references of any other kind. A document whose references are all cited by
all the documents has S = 0: its ties get a weight of 0.
Computing choices: see coupling_strength() (N counts all the
citing documents; duplicates and self-citations are ignored; missing
identifiers are dropped with a warning; the table of the user is not
modified; a zero-row table is returned, with a warning, if no
reference is shared). The same memory remark applies.
Versions up to 0.1.1 returned a different quantity, wrongly computed
(see NEWS.md): do not compare with their results.
Value
A data.table with one row per pair of documents sharing at
least weight_threshold references: the identifiers in from and to
(character if output_in_character = TRUE), the similarity in
weight (between 0 and 1), and the original identifiers in Source
and Target. Each pair appears once, with Source < Target.
Why use it in research
It combines the two qualities of the measures it generalises: like the
coupling strength, shared rare references count more than shared
classics; like the coupling angle, the weight is a cosine, bounded by 1,
and a long bibliography is normalised away. Use it when you want weights
with the same scale as the coupling angle (for instance to apply the same
threshold or community detection settings) while discounting the
references that all the corpus cites. (Shen et al. 2019)
find that, on a corpus of library and information science articles,
this similarity is very strongly correlated with the plain coupling angle
(a Pearson correlation of 0.996) and somewhat less with the coupling strength (0.887):
check on your own corpus, with correlate_weights(), whether it changes
anything.
Intuition
Start from the picture of coupling_strength(): the surprise of a shared
reference is \log(N/f). Now give every reference of a document an
importance equal to its surprise: a bibliography of ten classics carries
little information, a bibliography of ten obscure papers carries much. The
informational size S(A) of a document is the total surprise of its
bibliography, and the similarity compares the surprise that two documents
share with their informational sizes, like a cosine. Two documents with
short but distinctive bibliographies can be very similar, while two
documents with long bibliographies of classics cannot.
References
Sen SK, Gan SK (1983).
“A Mathematical Extension of the Idea of Bibliographic Coupling and Its Applications.”
Annals of library science and documentation, 30(2).
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_descriptive(),
coupling_jaccard(),
coupling_strength(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
coupling_similarity(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref")
# Toy example: for d3 and d4, N = 4, the shared reference r4 is cited by
# 2 documents, and S(d3) = 2 log(2), S(d4) = log(2) + log(4), so
# w = log(2) / sqrt(2 log(2) * 3 log(2))
toy <- data.frame(doc = c("d1", "d1", "d1", "d2", "d2", "d3", "d3", "d4", "d4"),
ref = c("r1", "r2", "r3", "r1", "r2", "r3", "r4", "r4", "r5"))
coupling_similarity(toy, source = "doc", ref = "ref")
Bibliographic coupling edges, weighted by the coupling strength
Description
Builds the edges of a bibliographic coupling network in which the shared
references are not all equal: sharing a reference that few documents cite
says more about the proximity of two documents than sharing a reference
that the whole corpus cites. The weight is the coupling strength
(Vladutz and Cook 1984; Shen et al. 2019), a refinement of the
coupling angle of coupling_angle() that gives each shared reference a
weight decreasing with its number of citations, in the spirit of the
inverse document frequency of information retrieval
(Spärck Jones 1972; Salton and Buckley 1988) (see
tf-idf).
Usage
coupling_strength(
dt,
source,
ref,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default). It applies to the number of shared references, not to the weight. |
output_in_character |
Logical. If |
Details
Write N for the number of citing documents in the table,
f_j for the number of documents citing reference j,
R(A) for the references of document A and L(A) = |R(A)|
for the length of its bibliography. The weight of the tie between A
and B is
w_{AB} = \frac{\sum_{j \in R(A) \cap R(B)} \log(N / f_j)}{L(A) \, L(B)}
A reference cited by every document has weight \log(1) = 0; a
reference cited by two documents has weight \log(N/2). Contrary to
the coupling angle, the denominator is the product (not the square root
of the product) of the lengths, and the weight is not bounded by 1; the
scale of the weights depends on N, so that the weights are
meaningful relative to each other within one call, not across calls.
This is Eq. 7 of (Shen et al. 2019), who use base-10
logarithms; the natural logarithm used here multiplies all the weights by
the same constant (\ln 10), which changes no ranking and no
correlation. Unlike coupling_similarity(), the lengths L are simple
counts of references, not sums of idf weights.
Computing choices:
-
Nis the number of distinct citing documents in the table, including those that share no reference with any other document; -
L(A)counts all the references ofA, including those cited by no other document; duplicated rows are counted once, a document citing itself is ignored, and rows with a missing identifier are dropped with a warning;
the table of the user is not modified;
if no reference is shared (or if no pair reaches
weight_threshold), a zero-row table is returned, with a warning that says why.
Memory: like all the coupling functions, it first lists all the pairs of
documents citing a same reference. A reference cited by n documents
creates n (n - 1) / 2 pairs, and very popular references can
exhaust the memory. Since such references have the smallest weights, they
can often be removed before the call with little effect on the result.
Value
A data.table with one row per pair of documents sharing at
least weight_threshold references: the identifiers in from and to
(character if output_in_character = TRUE), the coupling strength in
weight, and the original identifiers in Source and Target. Each
pair appears once, with Source < Target.
Why use it in research
In a corpus built around a topic (the stagflation literature, a journal, a decade of central-banking research), a few references are cited by most documents: they define the field but do not distinguish the documents within it. With the coupling angle, two documents sharing only such classics are as close as two documents sharing equally many rare references. The coupling strength corrects this, and makes the resulting network more suited to detecting sub-specialities. The cost is a measure that depends on the whole corpus: the weight of a tie changes if documents are added to the table, and is not comparable across corpora of different sizes (see below).
Intuition
Two economists who both cite the most famous paper of their field are not
necessarily working on the same question; two who both cite an obscure
working paper probably are. The coupling strength measures how surprising
a shared reference is: a reference cited by a fraction f/N of the
corpus has a surprise of \log(N/f), which is 0 for a reference
cited by everybody and grows as the reference gets rarer. The tie is the
total surprise of what two documents share, divided (as for the coupling
angle) by the lengths of the two bibliographies. It is the same logic as
the tf-idf of search engines, where a word found in every text does not
help to find a particular one.
References
Salton G, Buckley C (1988).
“Term-Weighting Approaches in Automatic Text Retrieval.”
Information Processing & Management, 24(5), 513–523.
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
Spärck Jones K (1972).
“A Statistical Interpretation of Term Specificity and Its Application in Retrieval.”
Journal of Documentation, 28(1), 11–21.
Vladutz G, Cook J (1984).
“Bibliographic Coupling and Subject Relatedness.”
Proceedings of the American Society for Information Science, 21, 204–207.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_descriptive(),
coupling_jaccard(),
coupling_similarity(),
coupling_vladutz(),
descriptive_terms()
Examples
library(biblionetwork)
coupling_strength(Ref_stagflation,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref")
# A toy example: d1 and d2 share r1 and r2, each cited by 2 of the
# 4 documents, so w = 2 * log(4 / 2) / (3 * 2)
toy <- data.frame(doc = c("d1", "d1", "d1", "d2", "d2", "d3", "d3", "d4", "d4"),
ref = c("r1", "r2", "r3", "r1", "r2", "r3", "r4", "r4", "r5"))
coupling_strength(toy, source = "doc", ref = "ref")
Bibliographic coupling edges, weighted by the Vladutz-Cook formula
Description
The first coupling measure that weights shared references by their
rarity, proposed by (Vladutz and Cook 1984) and reported
by (Shen et al. 2019) (their Eq. 6). It is the
ancestor of coupling_strength(), which (Shen et al. 2019)
present as a correction of it based on the probabilistic interpretation
of the inverse document frequency.
Usage
coupling_vladutz(
dt,
source,
ref,
weight_threshold = 1,
output_in_character = TRUE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
weight_threshold |
Number. The minimum number of shared references for two documents to be linked (1 by default: any shared reference creates a tie). A threshold of 2 or 3 is common in large corpora, where sharing a single reference is weak evidence of proximity and produces very dense networks. It applies to the number of shared references, not to the normalised weight. |
output_in_character |
Logical. If |
Details
Write f_j for the number of documents citing reference j and
L(A) for the length of the bibliography of A.
w_{AB} = \frac{4}{L(A) + L(B)} \sum_{j \in R(A) \cap R(B)} \frac{1}{f_j}
The factor 4 is a normalisation that changes no ranking. It makes the
weight reach 1 for two documents with identical bibliographies made of
references each cited by exactly two documents; since shared references
have f_j \geq 2, the weight is never above 1. Computing choices: see
coupling_strength().
Value
A data.table with one row per pair of documents sharing at
least weight_threshold references: from and to (character if
output_in_character = TRUE), the weight and the original
identifiers in Source and Target. Each pair appears once, with
Source < Target.
Why use it in research
It is provided mainly for comparison and replication: it also discounts
the references cited by many documents, but the weight of a reference
decreases as 1/f_j instead of \log(N/f_j), so that it
almost ignores all the references except the rarest ones. In the corpus
of (Shen et al. 2019) it differs markedly from the other
measures (correlations of about 0.6 to 0.7 with the relative coupling, the coupling angle, the coupling strength and the similarity). Use compute_couplings() and
correlate_weights() to see how much it matters on your corpus.
Intuition
A shared reference counts for the inverse of the number of documents that
cite it: a reference shared by two documents and cited by nobody else
counts 1/2, one cited by a hundred documents counts 1/100.
This is a very steep discount: the measure is almost entirely driven by the
rarest references. The sum is then divided by the average length of the two
bibliographies (the factor 4 is a convenient scaling). Compare with
coupling_strength(), whose discount (a logarithm) is much gentler.
References
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019).
“A Refined Method for Computing Bibliographic Coupling Strengths.”
Journal of Informetrics, 13(2), 605–615.
https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
Vladutz G, Cook J (1984).
“Bibliographic Coupling and Subject Relatedness.”
Proceedings of the American Society for Information Science, 21, 204–207.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_descriptive(),
coupling_jaccard(),
coupling_similarity(),
coupling_strength(),
descriptive_terms()
Examples
library(biblionetwork)
toy <- data.frame(doc = c("d1", "d1", "d1", "d2", "d2", "d3", "d3", "d4", "d4"),
ref = c("r1", "r2", "r3", "r1", "r2", "r3", "r4", "r4", "r5"))
coupling_vladutz(toy, source = "doc", ref = "ref")
Terms that describe why a document is related to another (DTerms)
Description
The second contribution of (Liu 2017): given two
documents, it extracts the words of the titles of the references of one
(to) that best indicate in what respect it is related to the other
(from). It complements coupling_descriptive(): the weight says how
much two documents are related, the terms say why.
Usage
descriptive_terms(
dt,
source,
ref,
title,
from,
to,
n_terms = 10,
stopwords = NULL
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents: they are the nodes of the coupling network. |
ref |
Character scalar. The column of the cited references. |
title |
Character scalar. The column with the title of the cited reference (one title per reference). |
from, to |
Identifiers of two documents (values of |
n_terms |
Number of terms to return. |
stopwords |
Character vector of words to ignore in the titles
( |
Details
The descriptive strength of a term t is (Eq. 6 of the paper)
D(t) = \frac{\sum_{r' \in R_{to},\, t \in T(r')} \max_{r \in R_{from}} \mathrm{Sim}(r, r')}{|R_{to}|}
with \mathrm{Sim} the reference similarity of coupling_descriptive().
The n_terms terms with the highest strength are returned (the paper
suggests about 10, the length of a title). The relation is not symmetric:
swap from and to to explain the relation the other way.
Value
A data.table with the term and its strength, in decreasing order.
Intuition
A document cites references for each of its issues. The references of
to that have a close match among the references of from are the
issues the two documents have in common, and the words of their titles
name these issues. A word is a good descriptor if it appears in many
references of to, and if these references are close to references of
from.
References
Liu R (2017). “A New Bibliographic Coupling Measure with Descriptive Capability.” Scientometrics, 110(2), 915–935. doi:10.1007/s11192-016-2196-7.
See Also
Other coupling measures:
biblio_coupling(),
coupling_angle(),
coupling_descriptive(),
coupling_jaccard(),
coupling_similarity(),
coupling_strength(),
coupling_vladutz()
Examples
library(biblionetwork)
toy <- data.frame(
doc = c("a", "a", "b", "b"),
ref = c("r1", "r2", "r1", "r3"),
title = c("inflation expectations", "oil supply shocks",
"inflation expectations", "supply shocks prices")
)
descriptive_terms(toy, "doc", "ref", "title", from = "a", to = "b")
Aggregate a coupling or co-citation network at the level of entities
Description
Builds the edges of a coupling (or co-citation) network whose nodes are
not documents but entities that aggregate documents: authors, journals,
institutions, countries... It is not a new measure of proximity: it takes
the measures of biblio_coupling() (or of biblio_cocitation()) and
computes them for entities instead of documents. Since an entity
publishes several documents, it can cite the same reference several
times, and the function takes this into account: citing a reference ten
times is more significant than citing it once. The counts are combined
with the minimum rule of Zhao and Strotmann (2008).
Usage
entity_network(
dt,
source,
ref,
entity,
network = c("coupling", "cocitation"),
method = c("angle", "strength", "similarity", "jaccard", "vladutz"),
weight_threshold = 1,
output_in_character = FALSE
)
Arguments
dt |
A data frame or a |
source |
Character scalar. The column of the citing documents.
Needed to count the documents, not to define the nodes (except for
|
ref |
Character scalar. The column of the cited references. |
entity |
Character scalar. The column of the entities that are the
nodes of the network (authors, journals, institutions...). With
|
network |
|
method |
The weighting method, one of |
weight_threshold |
Number. The minimum number of shared references for two entities to be linked (1 by default). With large entities such as journals, a higher value is advisable. |
output_in_character |
Logical. If |
Details
Write C_{Aj} for the number of times entity A cites reference
j (the number of its documents citing j), N for the
number of citing documents in the table, f_j for the number of
documents citing j, and L(A) = \sum_j C_{Aj} for the
total number of citations made by A. Write also
m_{AB}(g) = \sum_{j} \min(C_{Aj}, C_{Bj}) \, g_j, the overlap of the
two entities, with the references weighted by g_j. According to
method, the weight of the tie between A and B is
-
"angle", withg_j = 1:w_{AB} = \frac{m_{AB}(1)}{\sqrt{L(A) \, L(B)}} -
"strength", withg_j = \log(N / f_j):w_{AB} = \frac{m_{AB}(g)}{L(A) \, L(B)} -
"similarity", withg_j = \log(N / f_j)andS(A) = \sum_j C_{Aj} \log(N / f_j):w_{AB} = \frac{m_{AB}(g)}{\sqrt{S(A) \, S(B)}} -
"jaccard", withg_j = 1:w_{AB} = \frac{m_{AB}(1)}{L(A) + L(B) - m_{AB}(1)}which is the ratio of the sum of the minima to the sum of the maxima of the counts (the weighted Jaccard index);
-
"vladutz", withg_j = 1 / f_j:w_{AB} = \frac{4 \, m_{AB}(g)}{L(A) + L(B)}
The sums run over the references cited by both entities, and L, S
over all the references of the entity. The minimum of the two counts is
the number of times the two entities cite the reference "together"
(Zhao and Strotmann 2008). The package follows the paper for
the minimum rule with the coupling angle and strength; the other methods
are the same extension, applied to the measures of
coupling_similarity(), coupling_jaccard() and coupling_vladutz()
(the similarity is still bounded by 1, since
\min(C_{Aj}, C_{Bj}) \leq \sqrt{C_{Aj} C_{Bj}} and by the
Cauchy-Schwarz inequality). With a single citation per entity and
reference, each method gives back the document-level measure. f_j
counts citing documents, not entities, so that a document with several
authors is not counted several times. References cited by a single entity
cannot create a tie and are ignored in the overlaps, but they count in
L.
Co-citation. With network = "cocitation", the roles of source and
ref are swapped, as in biblio_cocitation(): the nodes are the entities
of the cited references, and the entity column must describe ref
(the author or the journal of the cited reference). Two entities are
co-cited when documents cite references of both. The formulas above apply
with the roles exchanged: C_{Aj} is the number of references of
A cited by document j.
The weight_threshold applies to the number of references shared by two
entities (each counted once, whatever the number of times it is cited).
The table of the user is not modified, rows with a missing identifier are
dropped with a warning, and a zero-row table is returned, with a warning, if no reference
is shared (or if no pair reaches weight_threshold). The memory warning
of coupling_strength() applies.
Value
A data.table with one row per pair of entities: from, to,
the weight, the original identifiers in Source and Target, and the
Weighting_method (the method). Each pair appears once, with Source < Target.
Why use it in research
Coupling at the level of authors (author bibliographic coupling,
(Zhao and Strotmann 2008)), journals or institutions maps
who relies on the same literature, whatever the documents they publish.
With network = "cocitation", it maps which authors, journals or
institutions are cited together, as in author co-citation analysis. It is
a way to study the structure of a discipline through its journals or its
authors, with fewer and denser nodes than the document-level network.
Because entities are aggregates of documents, check that they are not too
heterogeneous (a generalist journal citing everything is coupled with
everyone), and that the number of documents per entity is large enough to
give a stable bibliography. An article with several authors appears once
for each of its authors: the same document then contributes to several
entities.
Intuition
Think of an entity (say a journal) as one big bibliography made of the
bibliographies of all its documents, in which a reference appears as many
times as the entity's documents cite it. Two journals are close when their
big bibliographies overlap. Overlap is measured reference by reference by
the smaller of the two counts: if journal A cites a reference 10 times and
journal B twice, they share it twice (B is the limit). The methods then
differ in what they do with these overlaps, as their document-level
counterparts: "angle" only counts them and normalises by the sizes of the
two big bibliographies; "strength" counts a shared rare reference more
than a shared classic; "similarity" does the same but normalises by the
"informational size" of each big bibliography, to give a cosine that
cannot exceed 1; "jaccard" compares the overlap with the union of the
two big bibliographies; "vladutz" discounts popular references steeply.
References
Zhao D, Strotmann A (2008). “Author Bibliographic Coupling: Another Approach to Citation-Based Author Knowledge Network Analysis.” Proceedings of the American Society for Information Science and Technology, 45(1), 1–10. https://asistdl.onlinelibrary.wiley.com/doi/full/10.1002/meet.2008.1450450292.
Examples
library(biblionetwork)
Ref_stagflation$Citing_ItemID_Ref <- as.character(Ref_stagflation$Citing_ItemID_Ref)
# merging the references data with the citing author information in Nodes_stagflation
entity_citations <- merge(Ref_stagflation,
Nodes_stagflation,
by.x = "Citing_ItemID_Ref",
by.y = "ItemID_Ref")
entity_network(entity_citations,
source = "Citing_ItemID_Ref",
ref = "ItemID_Ref",
entity = "Author.y",
method = "angle")
# The same entities, linked when the documents of one cite the references of the other
# (nodes: the journals of the cited references, a column of Ref_stagflation)
head(entity_network(Ref_stagflation, source = "Citing_ItemID_Ref", ref = "ItemID_Ref",
entity = "Journal", network = "cocitation", weight_threshold = 2))
Put the weights of several measures side by side, with their ranks
Description
Joins a named list of edge tables (for instance the result of
compute_couplings()) by pair of nodes, with one column of weights per
element, and, by default, the rank of each pair under each measure and the
gap between the ranks of two measures. It is the table behind the other
comparison functions, and the tool to inspect the pairs on which two
measures disagree.
Usage
merge_weights(
edges,
rank = TRUE,
rank_gap = NULL,
ties = c("average", "min", "max", "first")
)
Arguments
edges |
A named list of edge tables, each with the columns |
rank |
Logical. If |
rank_gap |
Character vector of two names of |
ties |
How ties are ranked, as in |
Details
Weights of different measures do not have the same scale, but their ranks do: rank 1 is the strongest pair of the measure. A pair with a high weight for one measure and a low weight for another has a large gap between the two ranks. The gap is
\mathrm{rank\_gap}_{AB} = \mathrm{rank}_{2}(A, B) - \mathrm{rank}_{1}(A, B)
with 1 and 2 the first and second elements of rank_gap: it is positive
when the second measure ranks the pair lower (as less close) than the
first one, negative when it ranks it higher. Sorting the table on the gap
(decreasing, then increasing) gives the pairs on which the measures
disagree the most.
Ranks are computed on the pairs present in all the tables, so that they
are comparable: the pairs that a measure does not have (for instance
those of coupling_descriptive(), which links documents that share no
reference) get NA ranks.
Value
A data.table with Source, Target, one column of weights per
element of edges and, according to the arguments, the rank_<name>
columns and rank_gap. A pair absent from a table (for instance because
tables were built with different thresholds) gets NA.
See Also
Other tools to compare coupling measures:
compute_couplings(),
correlate_weights(),
overlap_top_weights(),
plot_weights(),
summarise_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
methods = c("angle", "strength"), weight_threshold = 2)
merged <- merge_weights(edges)
head(merged)
# The pairs that the angle ranks high and the strength ranks low
head(merged[order(-rank_gap)])
Overlap between the strongest edges of several measures
Description
For each pair of measures, the Jaccard index between the sets of their
strongest edges (the top share of the edges with the highest weights).
Correlations summarise all the edges, but a network analysis often relies
on the strongest ones (after a filtering of the weak ties). This function
tells how many of the strongest ties two measures have in common:
1 means the same strongest edges, 0 none in common.
Usage
overlap_top_weights(edges, top = 0.1)
Arguments
edges |
A named list of at least two edge tables, for instance from
|
top |
Share of edges kept for each measure, between 0 and 1 (0.1 by default: the top 10% of the edges). Ties at the threshold are all kept. |
Details
Value
A symmetric matrix of Jaccard indices, with the number of edges
kept by each measure in the attribute "n_top".
See Also
Other tools to compare coupling measures:
compute_couplings(),
correlate_weights(),
merge_weights(),
plot_weights(),
summarise_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
weight_threshold = 2)
overlap_top_weights(edges, top = 0.1)
Plot the weights of several coupling measures
Description
Two plots to compare coupling measures, in the spirit of the histograms and scatterplots of (Shen et al. 2019):
-
type = "distribution": one histogram of the weights per measure, each with its own horizontal scale (the measures do not share a scale); -
type = "scatter": the ranks of the pairs of nodes according to two measures (xandy). Points on the diagonal are ranked identically by both measures; ranks, rather than raw weights, are used because the scales differ.
It needs the ggplot2 and scico packages.
Usage
plot_weights(
edges,
type = c("distribution", "scatter"),
x = NULL,
y = NULL,
bins = 50
)
Arguments
edges |
A named list of edge tables, for instance from
|
type |
|
x, y |
For |
bins |
Number of bins of the histograms. |
Details
Value
A ggplot object.
References
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019). “A Refined Method for Computing Bibliographic Coupling Strengths.” Journal of Informetrics, 13(2), 605–615. https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other tools to compare coupling measures:
compute_couplings(),
correlate_weights(),
merge_weights(),
overlap_top_weights(),
summarise_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
weight_threshold = 2)
plot_weights(edges)
plot_weights(edges, type = "scatter", x = "angle", y = "strength")
Summarise the distribution of the weights of each measure
Description
Describes the distribution of the weights of each measure: number of
edges, mean, standard deviation, extremes, quantiles, and the share of
weights equal to zero. (Shen et al. 2019) compare the
measures through the shape of their distributions (they report a smooth,
right-skewed distribution, well fitted by a lognormal, for the idf-weighted
similarity, and more scattered and irregular ones for the other measures
except the raw count), which matters when the weights are used by a
community detection algorithm or filtered by a threshold. Read the
summaries with the scales in mind: a cosine is bounded by 1, the
coupling strength is not, so means and quantiles of different measures are
not comparable. The ratio_q99_median column, a scale-free indicator of
how heavy the right tail is, is.
Usage
summarise_weights(edges, probs = c(0.01, 0.25, 0.5, 0.75, 0.99))
Arguments
edges |
A named list of edge tables with a |
probs |
Numeric vector of probabilities for the quantiles. |
Details
Value
A data.table with one row per measure: method, n_edges,
mean, sd, min, one column per quantile (q01, q25...), max,
share_zero and ratio_q99_median.
References
Shen S, Zhu D, Rousseau R, Su X, Wang D (2019). “A Refined Method for Computing Bibliographic Coupling Strengths.” Journal of Informetrics, 13(2), 605–615. https://linkinghub.elsevier.com/retrieve/pii/S1751157716300244.
See Also
Other tools to compare coupling measures:
compute_couplings(),
correlate_weights(),
merge_weights(),
overlap_top_weights(),
plot_weights()
Examples
library(biblionetwork)
edges <- compute_couplings(Ref_stagflation, "Citing_ItemID_Ref", "ItemID_Ref",
weight_threshold = 2)
summarise_weights(edges)