Измерения центральности во взвешенной сети с использованием Statnet в R
Я создал взвешенную сеть, используя и igraph, и statnet в R. Я сейчас изучаю показатели централизации моей взвешенной сети, используя statnet, но полученные мной значения центральности, как будто statnet не учитывает значения моих ребер. Вот небольшой пример, чтобы проиллюстрировать мою проблему, используя показатель центральности степени.
Я создал свою сеть с помощью igraph:
nodes <- data.frame(id=c(1,2,3,4,5))
edges <- data.frame(source=c(1,1,2,2,3),
target=c(2,3,3,5,4),
weight=c(1,2,1,2,1))
library(igraph)
network <- graph_from_data_frame(d=edges, vertices=nodes, directed=FALSE)
Затем мне нужно было использовать пакет statnet, поэтому я преобразовал его следующим образом
network_statnet <- asNetwork(network)
detach("package:igraph", unload=TRUE)
library(statnet)
Затем я хотел вычислить центральность степени, сначала без учета значений ребер (degree_unweighted
), а затем с учетом значений ребер (degree_weighted
)
degree_unweighted<-degree(network_statnet, gmode="graph", ignore.eval=TRUE)
degree_weighted<-degree(network_statnet, gmode="graph", ignore.eval=FALSE)
Но в итоге я получаю те же самые меры центральности. Я не знаю, почему statnet не учитывает значения моих ребер, когда я указываю ignore.eval=FALSE
, У меня та же проблема с другими мерами центральности (между, близостью, собственным вектором).
1 ответ
Вы правы, degree
игнорирует вес независимо от ignore.eval
, Это видно в самой первой строке degree
где у нас есть
dat <- as.edgelist.sna(dat)
в то время как as.edgelist.sna
имеет параметр attrname
:
attrname - если x является сетевым объектом, (необязательный) атрибут ребра, который будет использоваться для получения значений ребер.
Так degree
на самом деле даже не пытается использовать какие-либо веса. Чтобы исправить это, мы можем переопределить эту функцию, добавив возможность использовать веса, как в
myDegree <- function (dat, g = 1, nodes = NULL, gmode = "digraph", diag = FALSE,
tmaxdev = FALSE, cmode = "freeman", rescale = FALSE, ignore.eval = FALSE, attrname = NULL)
{
dat <- as.edgelist.sna(dat, attrname = attrname)
if (is.list(dat))
return(sapply(dat[g], degree, g = 1, nodes = nodes, gmode = gmode,
diag = diag, tmaxdev = tmaxdev, cmode = cmode, rescale = rescale))
n <- attr(dat, "n")
if (gmode == "graph")
cmode <- "indegree"
if (tmaxdev) {
if (gmode == "digraph")
deg <- switch(cmode, indegree = (n - 1) * (n - 1 +
diag), outdegree = (n - 1) * (n - 1 + diag),
freeman = (n - 1) * (2 * (n - 1) - 2 + diag))
else deg <- switch(cmode, indegree = (n - 1) * (n - 2 +
diag), outdegree = (n - 1) * (n - 2 + diag), freeman = (n -
1) * (2 * (n - 1) - 2 + diag))
}
else {
m <- NROW(dat)
cm <- switch(cmode, indegree = 0, outdegree = 1, freeman = 2)
if (!(cmode %in% c("indegree", "outdegree", "freeman")))
stop("Unknown cmode in degree.\n")
deg <- .C("degree_R", as.double(dat), as.integer(m),
as.integer(cm), as.integer(diag), as.integer(ignore.eval),
deg = as.double(rep(0, n)), PACKAGE = "sna", NAOK = TRUE)$deg
if (rescale)
deg <- deg/sum(deg)
if (!is.null(nodes))
deg <- deg[nodes]
}
deg
}
Это тогда дает
(degree_unweighted <- myDegree(network_statnet, gmode = "graph", ignore.eval = TRUE))
# [1] 2 3 3 1 1
(degree_weighted <- myDegree(network_statnet, gmode = "graph", ignore.eval = FALSE, attrname = "weight"))
# [1] 3 4 4 1 2
Боюсь, вам понадобится такая же настройка для других функций, таких как betweenness
,