NukeDude
NukeDude

Reputation: 27

Eigenvector values for different time periods of same network (igraph in R)

Complete R rookie here, so please bear with me!

I have dyad-year data for trade between countries for a specific period of time. I'm trying to calculate eigenvector centrality values for each country in each separate year in the period 1946-2014. Second, I'd like to neatly package all these eigenvalues (with case labels and years) in a dataframe that can be exported to CSV.

Take the following example edges:

links <- structure(list(ccode1 = c(2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 2L, 
3L, 4L, 5L), ccode2 = c(5L, 4L, 3L, 2L, 5L, 4L, 3L, 2L, 
5L, 4L, 3L, 2L), year = c(1960, 1960, 1960, 1960, 1961, 1961, 1961, 1961, 1962, 1962, 1962, 1962), weight = c(1347.34, 778.42999, 
866.85999, 1014.14, 895.46002, 1082.0699, 1584.7, 1193.37, 1355.3101, 
1348.75, 3653.54, 616.98999)), row.names = c(NA, 12L), class = "data.frame")

The network would be constructed as follows:

network <- graph_from_data_frame(links, directed = FALSE, vertices = NULL)

And the eigenvalues would be calculated like so:

trade.eigen <- eigen_centrality(network, directed = FALSE)

1. How can I automate the calculation of eigenvalues for each country in each year?

2. And how would I combine all these values together with the country labels and years in one dataframe?

Upvotes: 0

Views: 211

Answers (1)

struggles
struggles

Reputation: 865

Thank you for providing an easily reproducible example. If I understand your problem correctly, all you need to do is:

  1. iterate through every year
  2. filter out edges that don't have the edge attribute associated with the year you are iterating over
  3. calculate the eigenvalues for the filtered graph
  4. store the outputs in a single data frame

The tidyverse family of packages have a lot of utility functions to make this easy. Use map to iterate, use enframe to change formats from key-value formats to data frame formats, then use unnest to clean things up.

# install.packages('tidyverse')
library(tidyverse)


#let's get all unique values for year
#we can do this by pulling the edge attribute
#"year" frome the graph "network"
years <- E(network)$year %>%
  unique


#now we want to use purrr's map to iterate through all the years
#the goal is to only keep edges from a year we are interested in
#"map" returns a list, and if we use the function "setNames", then
#each item in the list will be named after the object we are iterating
eigen_by_year <- purrr::map(setNames(years, years), function(yr){
  #here we filter away all edges that aren't from the year we are interested
  network_filtered = network - E(network)[year != yr]

  #we now calculate the eigen values for the filtered network
  eigen_values <- eigen_centrality(network_filtered, directed = F)$vector

  #"eigen_values" is a named vector, let's convert this named vector
  #into a data frame with the name column being the vertex name
  #and the value column being the eigen value
  tibble::enframe(eigen_values)
})

#The result is a list where the item names are the years
#and they contain a data frame of the eigen values associated
#with their years
eigen_by_year

#let's use enframe one more time so that the name of the list items
#are now their own "name" column and the nested data rames are
#in the "value" column" we will need to use unnest to flatten the dataframe
eigen_data_frame <- eigen_by_year %>%
  tibble::enframe() %>%
  tidyr::unnest()

eigen_data_frame

I hope this helps.

Upvotes: 1

Related Questions