在 R 中使用 Statnet 的加权网络中的中心性度量
Centrality Measures in a Weighted Network using Statnet in R
我在 R 中使用 igraph 和 statnet 创建了一个加权网络。我现在正在使用 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)
但我最终得到了完全相同的中心性度量。我不知道为什么当我指定 ignore.eval=FALSE
时 statnet 不考虑我的边缘值。我对其他中心性度量(介数、紧密度、特征向量)也有同样的问题。
你是对的,degree
忽略权重而不考虑 ignore.eval
。它在 degree
的第一行中可见
dat <- as.edgelist.sna(dat)
而 as.edgelist.sna
有一个参数 attrname
:
attrname - if x is a network object, the (optional) edge attribute to
be used to obtain edge values.
所以 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
。
我在 R 中使用 igraph 和 statnet 创建了一个加权网络。我现在正在使用 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)
但我最终得到了完全相同的中心性度量。我不知道为什么当我指定 ignore.eval=FALSE
时 statnet 不考虑我的边缘值。我对其他中心性度量(介数、紧密度、特征向量)也有同样的问题。
你是对的,degree
忽略权重而不考虑 ignore.eval
。它在 degree
的第一行中可见
dat <- as.edgelist.sna(dat)
而 as.edgelist.sna
有一个参数 attrname
:
attrname - if x is a network object, the (optional) edge attribute to be used to obtain edge values.
所以 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
。