The idea in this project is to create networks of policy preferences, and then test whether these networks are tied to government organizations. For example, the United States is a two-party system, and so you might expect that there are two large clusters of policy preferences: a liberal cluster (e.g. universal basic income, single payer healthcare) and a conservative cluster (e.g. gun rights, free speech). Governments with more diverse parliaments may have more complex clustering patterns of policy.
We are testing this idea by asking people to answer a series of yes-no questions about their policy preferences, and then to create adjacency matrices and networks based on their answers. Our eventual survey will contain people from 35 coutnries, and we have already piloted these questions (along with many other unrelated measures) in two samples of Americans. Here is some sample data from this pilot.
d<-read.csv("~/Desktop/policy_prefs.csv")
head(d[,2:31])
## limit_abortion background_checks voter_id death_penalty free_speech
## 1 1 1 1 1 1
## 2 1 1 1 1 1
## 3 1 1 1 0 1
## 4 1 1 1 1 1
## 5 0 1 0 0 1
## 6 1 0 1 0 1
## LGBT_marriage gender_equal marijuana_legal required_vaccine universal_income
## 1 1 1 1 1 1
## 2 1 1 1 1 1
## 3 0 0 1 1 0
## 4 0 1 1 1 0
## 5 1 1 1 0 1
## 6 1 1 1 0 0
## debt_relief anti_trust grad_tax foreign_tax reparations stock_freedom
## 1 1 1 1 1 1 1
## 2 1 1 1 1 1 1
## 3 0 0 1 1 0 1
## 4 1 1 1 0 0 1
## 5 1 1 1 0 1 1
## 6 0 1 0 1 0 0
## unions_bad school_mandatory free_college affirmative_action
## 1 1 1 1 1
## 2 1 1 1 1
## 3 0 0 1 1
## 4 1 1 0 1
## 5 0 1 1 1
## 6 1 1 0 0
## strict_immigration tradebills_good record_private reduce_CO2 carbon_tax
## 1 1 1 1 1 1
## 2 1 1 1 1 1
## 3 1 0 1 1 1
## 4 1 1 1 1 0
## 5 0 1 0 1 1
## 6 0 1 0 0 0
## endangered_protection single_payer reduce_drug_price regulate_drugs
## 1 1 1 1 1
## 2 1 1 1 1
## 3 1 0 1 1
## 4 0 1 1 1
## 5 1 1 1 1
## 6 1 0 1 1
## minimum_wage
## 1 1
## 2 1
## 3 1
## 4 1
## 5 1
## 6 0
In these data, “1” means that they agreed with a stance, and “0” indicates that they disagreed with it. The variable names are shorthand for the actual questions, which are as follows:
limit_abortion: “Do you believe in pro-life policies that reduce access to abortion?”
background_checks: “Do you support laws that mandate universal background checks for people who want to purchase firearms?”
voter_id: Do you believe that people must provide government-issued identification to vote in an election?
death_penalty: Do you support a death penalty for people who have committed particularly severe crimes?
free_speech: Do you believe that everyone, regardless of context or character, has a right to free speech?
LGBT_marriage: Do you believe that people in the LGBTQ+ community should have a right to marry who they choose?
gender_equal: Do you believe that all genders should earn equal wages for the same work?
marijuana_legal: Do you believe that marijuana should be legalized?
required_vaccine: Do you believe that people should be required to vaccinate their children against measles, mumps, and rubella?
universal_income: Do you believe in a universal basic income as a way to mitigate poverty?
debt_relief: Do you support student debt relief programs?
anti_trust: Do you support “anti-trust” policies that aim to prevent companies growing too large and powerful?
grad_tax: Do you support graduated income tax policies that prevent any person from becoming a billionaire?
foreign_tax: Do you believe that companies should pay a cost if they choose to manufacture their products in foreign countries?
reparations: Do you believe in reparation programs where national governments compensate aboriginal/first nation/native people for harms done during the colonial era?
stock_freedom: Do you believe that the national stock market should operate independently of government regulation?
unions_bad: Do you believe that labor unions hurt the economy?
school_mandatory: Do you believe that all children should be required to attend school until they are at least 16 years old?
free_college: Do you believe that public universities should be free of cost?
affirmative_action: Do you believe in affirmative action programs that give educational opportunities to people from underrepresented minority groups?
strict_immigration: Do you believe that immigration policies in your country need to be stricter?
tradebills_good: Do you believe that international trade bills are a good way to stimulate your nation’s economy?
record_private: Do you believe that the government has a right to record people’s private phone conversations during periods of national threat?
reduce_CO2: Do you believe in a tax on carbon in order to reduce CO2 emissions?
carbon_tax: Do you support policies that provide extra funding for the development of low-carbon products such as electric cars?
endangered_protection: Do you believe that endangered animals should be protected by the government?
single_payer: Do you believe in universal “single-payer” healthcare?
reduce_drug_price: Do you believe in reducing the price of prescription drugs to limit the control of pharmaceutical companies?
regulate_drugs: Should there be government regulations on the prices of medication developed by private insurance companies?
minimum_wage: Do you support raising the minimum wage?
Some of these items were endorsed more than others. The order of these bars corresponds to the order of the items above. The height of the bar is the percent of people who endorsed the policy preference. For example, just over 60% of people agreed with prolife policies that limited access to abortion.
If you delete people who agreed with every single preference, the means go down a litte but are pretty consistent.
We aren’t interested in the means, though. We are more interested in the co-occurence of policy preferences. To look at this co-occurence, I created an adjacency matrix from the binary data. In this matrix, the numbers correspond to the percentage of people who endorsed both items.
mat<-t(d[-1]) %*% as.matrix(d[-1])
diag(mat) <- 0
mat<-mat/947
From this matrix, I created a network where edges represent strength of co-endorsement. It’s undirected, and I got rid of the diagonals for obvious reasons.
library(igraph)
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
graph<-graph_from_adjacency_matrix(mat,weighted=T,diag = F,mode="undirected")
summary(graph)
## IGRAPH 7c2c9ae UNW- 30 435 --
## + attr: name (v/c), weight (e/n)
graph2<-simplify(graph,remove.loops = T,remove.multiple = F)
plot(graph2,vertex.size=10)
To give some structure to this network, I detected communities using the walktrap algorithm, which I’ve used in the past. Importantly, results change based on the community detection algorithm, which is something I’m hoping to get advice about. The walktrap communities make sense though. Most mainstream and conservative policies cluster into community 1, and very liberal policies cluster into community 2.
communities<-walktrap.community(graph2)
membership(communities)
## limit_abortion background_checks voter_id
## 1 1 1
## death_penalty free_speech LGBT_marriage
## 1 1 1
## gender_equal marijuana_legal required_vaccine
## 1 1 1
## universal_income debt_relief anti_trust
## 2 2 1
## grad_tax foreign_tax reparations
## 2 1 2
## stock_freedom unions_bad school_mandatory
## 1 1 1
## free_college affirmative_action strict_immigration
## 2 2 1
## tradebills_good record_private reduce_CO2
## 1 1 2
## carbon_tax endangered_protection single_payer
## 2 1 2
## reduce_drug_price regulate_drugs minimum_wage
## 1 1 2
Now I’ll plot them out using a more intuitive layout.
layout <-layout.fruchterman.reingold(graph2)
plot(graph2,
layout=layout,
vertex.size=.8*igraph::degree(graph2),
vertex.color=membership(communities),
edge.width = 10*edge_attr(graph2)$weight,
edge.color="black")
Finally, I saved some vertex attributes, and then read out the network to gephi where I created the visually prettier graph I sent you.
vertex_attr(graph2,"label")<-V(graph2)$name
vertex_attr(graph2,"weight")<-V(graph2)$weight
## Warning in length(vattrs[[name]]) <- vc: length of NULL cannot be changed
vertex_attr(graph2,"comms")<-membership(communities)
I would love to hear thoughts on whether my network creation process was accurate, whether we should explore other community detection options, and whether there are other network analyses that would be eventually helpful. I was thinking of eventually correlating the number of communities and modularity with the number of parties in a country’s government that receive at least n% of the vote in national elections, and exploring a variety of other outcomes (e.g. do countries with more modular networks have more political polarization?).