Dear igraph Development Team,
I hope this email finds you well. I’m writing to seek clarification on the eigenvector centralization calculation in the igraph package, specifically regarding the ‘scale’ parameter in the centr_eigen() function.
I’ve noticed some inconsistencies in the results when comparing igraph’s output with that of the sna package. My observations are as follows:
-
When calculating eigenvector centrality using eigen_centrality(), setting ‘scale = TRUE’ produces results consistent with sna’s evcent() function.
-
However, for eigenvector centralization using centr_eigen(), setting ‘scale = FALSE’ yields results consistent with sna’s centralization() function.
This discrepancy raises two important questions:
-
What exactly does the ‘scale’ parameter do in each of these functions, and why does it seem to have opposite effects?
-
Which setting should be used for the most accurate and comparable results across different network analysis packages?
Understanding these nuances is crucial for ensuring the accuracy and comparability of network analysis results. I would greatly appreciate any insights you can provide on this matter.
Thank you for your time and expertise.
Best regards,
Chuding
Below are the codes with annotations:
## Step 1: Create a 5x5 undirected and valued matrix
set.seed(123) # Set seed for reproducibility
matrix_values <- sample(1:4, 15, replace = TRUE) # Generate random weights for the upper triangle
undirected_matrix <- matrix(0, 5, 5) # Initialize a 5x5 matrix
# Fill the upper triangle with random values
undirected_matrix[upper.tri(undirected_matrix)] <- matrix_values
# Make the matrix symmetric to represent an undirected graph
undirected_matrix <- undirected_matrix + t(undirected_matrix)
undirected_matrix
## Step 2: Convert the matrix to an igraph object
library(igraph)
undirected_matrix_graph <- graph_from_adjacency_matrix(undirected_matrix,
mode = c("undirected"),
weighted = TRUE,
diag = FALSE)
## Step 3: Calculate eigenvector centrality
Eigenvector_centrality_from_igraph <- eigen_centrality(
undirected_matrix_graph,
directed = FALSE,
scale = TRUE,
weights = NULL)
Eigenvector_centrality_from_igraph <- data.frame(Eigenvector_centrality_from_igraph = Eigenvector_centrality_from_igraph$vector)
library(sna)
Eigenvector_centrality_from_sna <- evcent(undirected_matrix,
g=1,
nodes=NULL,
gmode="graph",
diag=FALSE,
tmaxdev=FALSE,
rescale=FALSE,
ignore.eval=FALSE,
tol=1e-10,
maxiter=1e5,
use.eigen=FALSE)
detach("package:sna", unload=TRUE)
Eigenvector_centrality_from_sna <- Eigenvector_centrality_from_sna / max(Eigenvector_centrality_from_sna)
Eigenvector_centrality_from_sna <- data.frame(Eigenvector_centrality_from_sna = Eigenvector_centrality_from_sna)
# Combine and compare the results of eigenvector centrality from igraph and sna
CombinedResults <- cbind(Eigenvector_centrality_from_igraph, Eigenvector_centrality_from_sna)
CombinedResults
cor(CombinedResults)
## Step 4: Calculate eigenvector centralization
# If we change this to "scale = TRUE" into "scale = FALSE", the results will be consistent.
# But when calculating eigenvector centrality, this is set as TRUE.
# And the results above are consistent with those from sna.
Eigenvector_centralization_from_igraph <- centr_eigen(
undirected_matrix_graph,
directed = FALSE,
scale = TRUE,
options = arpack_defaults(),
normalized = TRUE
)
Eigenvector_centralization_from_igraph <- Eigenvector_centralization_from_igraph$centralization
library(sna)
Eigenvector_centralization_from_sna <- centralization(undirected_matrix,
FUN=evcent,
g=NULL,
mode="graph",
diag=FALSE,
normalize=TRUE)
detach("package:sna", unload=TRUE)
# Combine and compare the results of eigenvector centralization from igraph and sna
CombinedResults <- cbind(Eigenvector_centralization_from_igraph, Eigenvector_centralization_from_sna)
CombinedResults