gpt4 book ai didi

r - iGraph 和 disparityfilter 包问题与字符和大数字

转载 作者:行者123 更新时间:2023-12-04 11:54:01 25 4
gpt4 key购买 nike

在从未收到我将在下面提到的创建包的两位作者的回复之后,我认为这里的某个人可以对这个问题有所了解。

我正在使用一个大型数据集,其中包括 Origin Destination 对,以及从 A 到 B 的各个乘客。Origin 和 Destination 变量都使用 IATA 机场名称(3 个字母)进行编码。
原始 csv 文件可以在这里找到 https://github.com/FilipeamTeixeira/network .
请注意,所有 3 个 csv 文件都相同,除了一个将 ORIGIN/DEST 变量作为字符,另一个作为数字,第三个作为更大的数字。但是出于网络目的,它们完全相同,因为它们提供相同数量的连接。

    ORIGIN  DEST    weight
ABE ATL 1530
ABE AVP 6
ABE BDL 2
ABE BOS 1
ABE BWI 3
ABE CLT 1053

导入文件后,我用 a <- graph_from_data_frame(netchr, directed = TRUE) 创建了一个新图。 .

然后,由于我通常使用大型数据集,我使用视差过滤器 https://github.com/alessandrobessi/disparityfilter/blob/master/R/disparity_filter.R ,找到我的网络的 Backbone 结构,并减少边/节点的数量。

为此,我运行 backbone(a) .

现在的问题是,只要原始数据框将 Origin 和 Destination 变量作为字符或超过 4 位数字的数字,它就会返回 0。但是,当原始数据框具有这两个 3 位数字的变量时,它工作得很好它返回一些结果。

运行下面的代码,可以清楚地了解问题。
# Import network
# Imports csv

netchr <- read.csv("netchr.csv", header = TRUE,sep = “,”, stringsAsFactors = FALSE)

netnumber <- read.csv("netnum.csv", header = TRUE, sep = “,”, stringsAsFactors = FALSE)

netnumber2 <- read.csv("netnum2.csv", header = TRUE, sep = “,”, stringsAsFactors = FALSE)

# Load igraph and dispfilter

library(igraph)
library(disparityfilter)

a <- graph_from_data_frame(netchr, directed = TRUE)

b <- graph_from_data_frame(netnumber, directed = TRUE)

c <- graph_from_data_frame(netnumber2, directed = TRUE)

# Create backbone network

backbone(a) # finds 0

backbone(b) # has results

backbone(c) # finds 0

我真的很难理解可能会发生什么,因为即使 iGraph 创建图形,它也会将节点转换为字符,所以从逻辑上讲,最后一切都应该是相同的。

最佳答案

该问题源于 disparityfilter 包中的错误。 disparity_filter 的内部结构函数,由 backbone() 调用,涉及将节点名称与节点索引进行比较(一个错误),因此该函数仅在节点名称与节点索引相等时才起作用。需要明确的是,这意味着在一般情况下(您的示例中的情况 b),结果可能无论如何都是错误的——尽管有些东西正在返回。

将索引与名称进行比较是该函数不返回任何字符的原因,也是它不返回任何大数字的原因:如果数字的大小超过网络中的节点数,则永远不会发生匹配。

我将进行演示,然后指出代码中的问题所在。然后,我将快速展示结果与当前存在的代码版本的不同之处,以及导致“正确”输出的快速“修复”(丑陋的 hack)(我害怕引用正确,因为我不知道) t 真的知道输出应该是什么或如何测试它)。

复制你的发现

好的,到您的网络文件的链接已损坏,因此我将使用 igraphdata 中的一些数据包裹:

# Load the requisite libraries
library(igraph)
library(disparityfilter)
library(igraphdata)

# We'll use the enron email network (b/c cool)
data(enron)

# convert it to a df
df <- igraph::as_data_frame(enron, what = 'edges')
summary(df) # we see nodes numbered from 1:184
#> from to Time Reciptype
#> Min. : 1.0 Min. : 1 Length:125409 Length:125409
#> 1st Qu.: 64.0 1st Qu.: 64 Class :character Class :character
#> Median :108.0 Median :113 Mode :character Mode :character
#> Mean :105.4 Mean :108
#> 3rd Qu.:156.0 3rd Qu.:156
#> Max. :184.0 Max. :184
#> Topic LDC_topic
#> Min. :0.000 Min. :-1.000
#> 1st Qu.:1.000 1st Qu.: 0.000
#> Median :1.000 Median : 0.000
#> Mean :1.711 Mean : 2.572
#> 3rd Qu.:3.000 3rd Qu.: 1.000
#> Max. :3.000 Max. :32.000

# create a weights variable
df$weight <- df$Topic

现在让我们创建字符和大量版本的顶点名称

# Create a char version of the nodes by appending 'char' to the number
dfchar <- df
dfchar$from <- paste0("char", dfchar$from)
dfchar$to <- paste0("char", dfchar$to)

# create a big num version
dfbnum <- df
dfbnum$from <- 1000 * dfbnum$from
dfbnum$to <- 1000 * dfbnum$to

现在我们将 data.frames 转换回图形

# Now convert the DFs back to graphs
smallnum <- graph_from_data_frame(df, directed = TRUE)

chars <- graph_from_data_frame(dfchar, directed = TRUE)

bignum <- graph_from_data_frame(dfbnum, directed = TRUE)

然后我们可以运行 backbone()跨这三个图表复制您的发现:

## Now we document what you found: namely the anomolous behavior of backbone
newbbs <- backbone(smallnum)
dim(newbbs)
#> [1] 231 4

newbbc <- backbone(chars)
dim(newbbc)
#> [1] 0 4

newbbb <- backbone(bignum)
dim(newbbb)
#> [1] 0 4

所以正如您所指出的,即使在其他数据上 backbone()除非节点被标记为通用 1:N,否则函数找不到匹配项.

发现问题

好的,到目前为止,我正在复制您记录的内容。我们如何知道其内部的索引问题 backbone() ?首先让我告诉你,如果我们让节点的名称比它们的索引大一点会发生什么:

# now to demonstrate the indexing issue quickly, lets increment
# the node names just a bit, and see what gets returned.
# create a medium num version
dfmnum <- df
dfmnum$from <- dfmnum$from + 90 #add about half the number of nodes to the name
dfmnum$to <- dfmnum$to + 90

# convert back to graph
midnum <- graph_from_data_frame(dfmnum)
bbmid <- backbone(midnum)
dim(bbmid)
#> [1] 28 4

正如您所看到的,这极大地改变了函数的性能——我们找到了 28 个,而不是找到 231 个结果!原因是现在有一半的节点名称没有与索引匹配,大约有一半是 - 所以我们得到了随机(并且完全不正确)的结果。

问题出在哪儿?
disparityfilter包在 github 上,由文件 disparity_filter.R 组成,可以看到 here .在线58 disparity_filter函数转换 backbone() 中提供的图形回到数据框。让我们用我们的“字符”版本的图表来做这件事:

e <- igraph::as_data_frame(chars)[,1:2]
head(e)
from to
1 char25 char154
2 char25 char154
3 char30 char30
4 char30 char30
5 char30 char30
6 char30 char30

正如我们所看到的,这里的 from 和 to 列具有我们为其分配的名称。然后从第 63 行开始, disparity_filter()函数循环遍历度数 ( d ) 大于 1 的情况,行 for (u in which(d > 1)) .然后在 switch第 65 行的语句在节点名称和索引 u 之间进行了一系列比较:

w = switch(substr(mode, 1, 1),
a = which(e[, 1] == u | e[, 2] == u),
i = which(e[, 2] == u),
o = which(e[, 1] == u)
)

这显然是不正确的,并且只有在节点的名称碰巧与其索引匹配时才有效。明确地说,使用我们的 chars版本图 u的第一个值将是 1 对应于节点 char25 .值 char25存在于向量中 e[,1]但当然永远不会与索引匹配——尽管这可能是作者的意图。同样的问题在下面的 switch() 中重复出现从第 76 行开始的语句。由于没有匹配项,因此当节点具有非数字名称或数字名称超过节点数时,不会返回任何内容。

问题有多严重?

好的,那么如果节点的名称从 1 开始计数呢?让我们来看看 u 的值是多少和 e[,1]将是。我们将使用具有“有效”顶点名称的图形版本:

d <- degree(smallnum)
which(d>1)
25 30 39 52 61 64 66 67 93 100 115 125 138 141 146 156 164 168 170
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

正如我们所看到的,顶点的数字名称无论如何都不对应于索引!因此,即使在返回某些东西的情况下,我们也只是在返回噪音。快速编辑以查看差异;我们将重命名顶点,使它们对应于它们的索引:

renamed <- set.vertex.attribute(smallnum, "name", value=1:length(V(smallnum)))
bbs_problem_revealed <- backbone(renamed)
dim(bbs_problem_revealed)
[1] 9 4

好的,现在索引与顶点匹配,我们只得到 9 个观察值!显然,该功能出了点问题。这个新答案正确吗?老实说,我不确定,因为我不确定输出应该是什么或如何验证它。此外,如果我要依赖代码,我真的想重新进行比较以将名称与名称匹配。

无论如何,我的建议是在包作者有机会修复它之前不要使用这个函数。我将在github上打开一个错误报告。

关于r - iGraph 和 disparityfilter 包问题与字符和大数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43387316/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com