This vignette briefly illustrates how to use the
incidentally
package to obtain data on bill sponsorship in
US Congress, and how to use the backbone
package to
construct political networks from these data. For a more detailed
tutorial, please see:
Neal, Z. P. (2022). Constructing legislative networks in R using incidentally and backbone. Connections. https://doi.org/10.2478/connections-2019.026
For a more general introduction to the incidentally
package, see the main vignette. The
incidentally
package can be cited as:
Neal, Z. P. (2022). incidentally: An R package to generate incidence matrices and bipartite graphs. OSF Preprints. https://doi.org/10.31219/osf.io/ectms
If you have questions about the incidentally package or would like an incidentally hex sticker, please contact the maintainer Zachary Neal by email (zpneal@msu.edu). Please report bugs in the incidentally package at https://github.com/zpneal/incidentally/issues.
In the US Congress, bills may become laws through a multi-step legislative process:
The vast majority of introduced bills are never formally voted on, and never become law, because they fail to pass one of these legislative hurdles. Therefore, focusing only on votes or passage provides limited information about legislators’ politcial positions. In contrast, because all introduced bills have sponsors and co-sponsors, legislators’ sponsorship behaviors provides rich data on their political positions.
There are four types of legislation that can be introduced in the US Congress:
Because bills and joint resolutions can become laws, these often provide more information about legislators’ political positions than concurrent and simple resolutions, which are used only for procedural matters.
When any type of legislation is introduced, the Congressional Research Service assigns it to one of 32 broad policy areas. A complete list of policy areas and brief descriptions is available at https://www.congress.gov/help/field-values/policy-area.
The incidence.from.congress()
function in the
incidentally
package makes it easy to get data on
legislators’ bill sponsorship activities. The incidentally
package can be loaded in the usual way:
library(incidentally)
#> O O O incidentally v1.0.3
#> |\ | /| Cite: Neal, Z. P. (2022). incidentally: An R package for generating incidence matrices
#> | | | and bipartite graphs. CRAN. https://doi.org/10.32614/CRAN.package.incidentally
#> |/ | \| Help: type vignette("incidentally"); email zpneal@msu.edu; github zpneal/incidentally
#> X X X Beta: type devtools::install_github("zpneal/incidentally", ref = "devel")
Upon successful loading, a startup message will display that shows the version number, citation, ways to get help, and ways to contact me.
Now we can use the incidence.from.congress()
function to
get data on legislators’ bill sponsorship activities:
I <- incidence.from.congress(session = 115, types = c("sres"), areas = c("All"), format = "data", narrative = TRUE)
#> Retriving bills from session 115
#> Examining 747 bills
#>
#> === Suggested manuscript text and citations ===
#> We used the incidentally package for R (v1.0.3; Neal, 2022) to generate an incidence matrix recording Senators' bill sponsorships during the 115 session of the US Congress.
#>
#> Neal, Z. P. 2022. Constructing legislative networks in R using incidentally and backbone. Connections, 42. https://doi.org/10.2478/connections-2019.026
In this example, we request data on Senate simple resolutions
(types = c("sres")
) in all policy areas
(areas = "All")
) that were introduced during the 115th
session (session = 115
), which took place between January
3, 2017 and January 3, 2019. Running this command can take some time
because many bills must be downloaded and parsed, but a progress bar is
displayed. By specifying narrative = TRUE
, the function
generates suggested text and citations for describing what it has done.
By specifying format = "data"
, the resulting object
I
is a list containing (1) an incidence matrix recording
which legislators sponsored or co-sponsored which bills, (2) a data
frame of legislator characteristics, and (3) a data frame of bill
characteristics:
I$matrix[1:5,1:5]
#> SRES274 SRES575 SRES123 SRES421 SRES174
#> Sen. Alexander, Lamar [R-TN] 1 1 1 1 1
#> Sen. Blunt, Roy [R-MO] 0 1 0 1 1
#> Sen. Brown, Sherrod [D-OH] 0 1 0 1 0
#> Sen. Burr, Richard [R-NC] 0 1 0 1 0
#> Sen. Baldwin, Tammy [D-WI] 0 1 0 1 0
I$legislator[1:5,1:5]
#> id name last party state
#> 1 A000360 Sen. Alexander, Lamar [R-TN] Alexander R TN
#> 52 B000575 Sen. Blunt, Roy [R-MO] Blunt R MO
#> 118 B000944 Sen. Brown, Sherrod [D-OH] Brown D OH
#> 238 B001135 Sen. Burr, Richard [R-NC] Burr R NC
#> 289 B001230 Sen. Baldwin, Tammy [D-WI] Baldwin D WI
I$bills[1:5,c(1,2,4,5)]
#> bill introduced area sponsor.party
#> 1 SRES274 2017-09-28 finance and financial sector R
#> 2 SRES575 2018-07-12 crime and law enforcement D
#> 3 SRES123 2017-04-07 public lands and natural resources D
#> 4 SRES421 2018-03-01 crime and law enforcement R
#> 5 SRES174 2017-05-18 social welfare R
Using the same parameters, but specifying
format = "igraph"
yields an igraph bipartite graph
B
that includes the legislator and bill characteristics as
vertex attibutes:
B <- incidence.from.congress(session = 115, types = c("sres"), areas = c("All"), format = "igraph")
#> Retriving bills from session 115
#> Examining 747 bills
B
#> IGRAPH d324914 UN-B 851 7909 --
#> + attr: name (v/c), type (v/l), party (v/c), state (v/c), last (v/c),
#> | id (v/c), color (v/c), introduced (v/c), title (v/c), area (v/c),
#> | sponsor.party (v/c), partisan (v/n), status (v/c)
#> + edges from d324914 (vertex names):
#> [1] Sen. Alexander, Lamar [R-TN]--SRES274 Sen. Alexander, Lamar [R-TN]--SRES575
#> [3] Sen. Alexander, Lamar [R-TN]--SRES123 Sen. Alexander, Lamar [R-TN]--SRES421
#> [5] Sen. Alexander, Lamar [R-TN]--SRES174 Sen. Alexander, Lamar [R-TN]--SRES292
#> [7] Sen. Alexander, Lamar [R-TN]--SRES69 Sen. Alexander, Lamar [R-TN]--SRES455
#> [9] Sen. Alexander, Lamar [R-TN]--SRES184 Sen. Alexander, Lamar [R-TN]--SRES485
#> [11] Sen. Alexander, Lamar [R-TN]--SRES117 Sen. Alexander, Lamar [R-TN]--SRES682
#> + ... omitted several edges
The bill sponsorship data generated by
incidence.from.congress()
can be examined in a variety of
ways. However, one common used of bill sponsorship data is the
construction of a bill co-sponsorship network. In a bill co-sponsorship
network, two legislators are connected if they sponsored or co-sponsored
the same bills, which provides evidence of their political alignment and
possibly that they are political allies. One key challenge in
constructing co-sponsorship networks is deciding how many bills two
legislators must (co-)sponsor together before inferring they are aligned
or allies (Neal 2014,
2020). The backbone
package offers several methods for making these inferences.
The backbone
package can be loaded in the usual way:
library(backbone)
#> ____ backbone v2.1.4
#> | _ \ Cite: Neal, Z. P., (2022). Backbone: An R package to extract network backbones.
#> |#|_) | PLOS ONE, 17, e0269137. https://doi.org/10.1371/journal.pone.0269137
#> |# _ <
#> |#|_) | Help: type vignette("backbone"); email zpneal@msu.edu; github zpneal/backbone
#> |____/ Beta: type devtools::install_github("zpneal/backbone", ref = "devel")
Upon successful loading, a startup message will display that shows the version number, citation, ways to get help, and ways to contact me.
Given the bipartite igraph object generated by
incidence.from.congress()
above, we can generate a
political network among the Senators using:
network <- sdsm(B, alpha = 0.05, narrative = TRUE)
#>
#> === Suggested manuscript text and citations ===
#> We used the backbone package for R (v2.1.4; Neal, 2022) to extract the unweighted backbone of the weighted projection of an unweighted bipartite network containing 104 agents and 747 artifacts. An edge was retained in the backbone if its weight was statistically significant (alpha = 0.05) using the stochastic degree sequence model (SDSM; Neal, 2014). This reduced the number of edges by 89.5%, and reduced the number of connected nodes by 4.8%.
#>
#> Neal, Z. P. 2022. backbone: An R Package to Extract Network Backbones. PLOS ONE, 17, e0269137. https://doi.org/10.1371/journal.pone.0269137
#>
#> Neal, Z. P. (2014). The backbone of bipartite projections: Inferring relationships from co-authorship, co-sponsorship, co-attendance and other co-behaviors. Social Networks, 39, 84-97. https://doi.org/10.1016/j.socnet.2014.06.001
network
#> IGRAPH 9133ae6 UN-- 104 560 --
#> + attr: name (v/c), party (v/c), state (v/c), last (v/c), id (v/c),
#> | color (v/c)
#> + edges from 9133ae6 (vertex names):
#> [1] Sen. Alexander, Lamar [R-TN]--Sen. Corker, Bob [R-TN]
#> [2] Sen. Alexander, Lamar [R-TN]--Sen. Enzi, Michael B. [R-WY]
#> [3] Sen. Alexander, Lamar [R-TN]--Sen. Portman, Rob [R-OH]
#> [4] Sen. Alexander, Lamar [R-TN]--Sen. Scott, Tim [R-SC]
#> [5] Sen. Blunt, Roy [R-MO] --Sen. Boozman, John [R-AR]
#> [6] Sen. Blunt, Roy [R-MO] --Sen. Cassidy, Bill [R-LA]
#> [7] Sen. Blunt, Roy [R-MO] --Sen. Cotton, Tom [R-AR]
#> + ... omitted several edges
The stochastic degree sequence model (SDSM) connects two
legislators if they (co-)sponsored statistically significantly (at the
alpha = 0.05
level) more bills together than would be
expected if (a) their total number of sponsorships was approximately the
same and (b) each bill’s total number of sponsorships was approximately
the same, but (c) they randomly chose which bills to sponsor. Because we
started with an igraph object B
, the result is also an
igraph object network
that contains the Senators’
characteristics as vertex attributes. By specifying
narrative = TRUE
, the function generates suggested text and
citations for describing what it has done.
We can use the igraph
package to plot this network,
coloring each node by political party:
This network clearly shows the partisan structure of the US Senate: Democrats (blue) mostly work with other Democrats, and Republicans (red) mostly work with other Republicans.
We can also generate a signed political network:
where Senators that sponsor significantly many bills are connected by a positive tie that might indicate alliance, while Senators that sponsor significantly few bills are connected by a negative tie that might indicate opposition.
Again, using the igraph
package to plot this
network:
E(signed)$color <- rgb(0,1,0,1) #Define color of positive edges
E(signed)$color[which(E(signed)$sign==-1)] <- rgb(1,0,0,.05) #Define color of negative edges
layout <- layout_nicely(delete_edges(signed, which(E(signed)$sign==-1))) #Get layout based on positive edges
plot(signed, vertex.label = NA, vertex.frame.color = NA, vertex.size = 10, layout = layout)
This network still shows the partisan structure of the US Senate, but illustrates that there are positive ties within-party and negative ties between-party.