我正在尝试复制一般网络分析 R 'igraph' 包代码中似乎缺少的措施。我能找到的最好的方法是“igraph”包中的命令,但这只提供了银行名称列表,没有我需要的数字。
问题中提供的数据片段仅包含来自单个银行的传出连接,因此不足以演示问题的解决方案。这是一个可复制的玩具示例,应该足够了:
library(igraph)
set.seed(1)
d <- replicate(2, sample(paste("Bank", LETTERS[1:10]), 10, TRUE)) |>
as.data.frame()
d <- unique(d[d[[1]] != d[[2]], ])
data <- graph_from_data_frame(d)
plot(data)
根据我对您的方法论论文的阅读,LSCC 是数据集中从每家银行可以到达的其他银行的比例,仅遵循传出边缘。我们可以使用函数
igraph
找到这是 subcomponent
。例如,要查找我们可以从银行 B 联系到的所有银行,我们可以这样做:
subcomponent(data, V(data)["Bank B"], "out")
#> + 5/9 vertices, named, from 4b4f304:
#> [1] Bank B Bank G Bank E Bank I Bank F
您可以确认在上面的例子中银行G、E、I和F都可以从银行B到达。
我们有兴趣获得银行 B 可以到达的所有银行(不包括其本身)的比例。这只是子组件中的节点数(减去银行 B)除以银行总数(减去银行 B)。换句话说:
(length(subcomponent(data, V(data)["Bank B"], "out")) - 1) / (length(V(data)) - 1)
#> [1] 0.5
这个数字意味着从银行 B 可以到达一半的其他银行。
要获取所有银行的结果,我们可以使用
lapply
:
result <- lapply(V(data), function(v) {
(length(subcomponent(data, v, "out")) - 1) / (length(V(data)) - 1)
})
result
#> $`Bank I`
#> [1] 0.125
#>
#> $`Bank D`
#> [1] 0.125
#>
#> $`Bank G`
#> [1] 0.375
#>
#> $`Bank A`
#> [1] 0.375
#>
#> $`Bank B`
#> [1] 0.5
#>
#> $`Bank C`
#> [1] 0.25
#>
#> $`Bank E`
#> [1] 0.125
#>
#> $`Bank J`
#> [1] 0
#>
#> $`Bank F`
#> [1] 0
如果您希望将其放入数据框中,您可以这样做:
result |>
as.data.frame(check.names = FALSE) |>
t() |>
as.data.frame() |>
tibble::rownames_to_column() |>
setNames(c('Bank', "LSCC")) |>
dplyr::arrange(Bank)
#> Bank LSCC
#> 1 Bank A 0.375
#> 2 Bank B 0.500
#> 3 Bank C 0.250
#> 4 Bank D 0.125
#> 5 Bank E 0.125
#> 6 Bank F 0.000
#> 7 Bank G 0.375
#> 8 Bank I 0.125
#> 9 Bank J 0.000
根据 Allan Cameron 的回答中的数据,这里有两个计算 LSCC 的函数。
library(igraph)
LSCC1 <- function(x) {
d <- distances(x, mode = "out")
rowSums(d > 0L & is.finite(d))/(length(V(x)) - 1L)
}
LSCC2 <- function(x) {
paths <- lapply(V(x), \(v) all_shortest_paths(x, from = v, mode = "out"))
sapply(paths, \(p) {
sum(p[["nrgeo"]] > 0) - 1L
})/(length(V(x)) - 1L)
}
LSCC1(data)
#> Bank I Bank D Bank G Bank A Bank B Bank C Bank E Bank J Bank F
#> 0.125 0.125 0.375 0.375 0.500 0.250 0.125 0.000 0.000
LSCC2(data)
#> Bank I Bank D Bank G Bank A Bank B Bank C Bank E Bank J Bank F
#> 0.125 0.125 0.375 0.375 0.500 0.250 0.125 0.000 0.000
创建于 2024-08-25,使用 reprex v2.1.0
要输出 data.frame,请通过管道连接到
as.data.frame
,然后修复列名称。在下面的输出中,行名称是顶点的名称。
LSCC1(data) |> as.data.frame()
#> LSCC1(data)
#> Bank I 0.125
#> Bank D 0.125
#> Bank G 0.375
#> Bank A 0.375
#> Bank B 0.500
#> Bank C 0.250
#> Bank E 0.125
#> Bank J 0.000
#> Bank F 0.000
创建于 2024-08-25,使用 reprex v2.1.0