該問題源於disparityfilter包中的一個錯誤。由backbone()
調用的disparity_filter
函數的內部涉及將節點名稱與節點索引(一個bug)進行比較,並且因此該函數僅在節點名稱碰巧等於節點索引時才起作用。清楚的是,這意味着在一般情況下(例如你的例子b),結果是,無論如何都可能是錯誤的--儘管有些東西正在返回。
將索引與名稱進行比較是函數不返回任何含有字符的原因,也是它不返回任何大數字的原因:如果數字的大小超過了網絡匹配中的節點數從不發生。
我將演示,然後指出問題出現在代碼中的位置。然後,我會很快顯示結果與當前存在的代碼版本的不同以及導致「正確」輸出的快速「修復」(醜陋的黑客攻擊)有多不同(我是嚇人的引用是正確的,噸真的知道輸出應該是什麼或如何測試)。
複製您發現
OK,你的網絡文件的鏈接被打破,所以我會從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
現在讓我們創建字符和large-頂點名稱的數字版本
# 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轉換回gr APHS
# 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
正如你可以看到這極大地改變了功能的性能 - 而不是找到231個結果我們」已經找到了28!原因是現在有一半的節點名稱與索引沒有匹配,大約有一半 - 所以我們得到了隨機(並且完全不正確)的結果。
問題在哪裏?
disparityfilter
軟件包位於github上,由文件disparity_filter.R組成,文件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
正如我們從和列在這裏有我們賦予他們的名字見。然後從行63開始,disparity_filter()
函數會循環使用行for (u in which(d > 1))
的程度(d
)大於1的情況。然後在第65行上switch
聲明一系列比較的節點的名稱和指數ü兩種情況:
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]
中,但當然不會與索引匹配 - 儘管這是作者推測的意圖。在第76行開始的switch()
語句中重複出現了同樣的問題。由於沒有匹配,當節點具有非數字名稱或數字名稱超過節點數時,不會返回任何結果。
問題有多嚴重?
好吧,那麼節點的名稱從一個起算的情況如何呢?讓我們來看看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
OK,我們只得到9個觀察回:所以他們對應的指數,我們將重命名的頂點!顯然,該功能有些問題。這個新答案是否正確?老實說,我不確定,因爲我不確定輸出應該是什麼,或者我可以如何驗證它。此外,如果我要依賴代碼,我想真正重做比較以匹配名稱和名稱。
無論如何,我的建議是,除非軟件包作者有機會修復它,否則不要使用這個函數。我將在github上打開一個bug報告。
我已經在幾個月前在github上創建了一個bug報告,他們從未回覆過。但事實上,你對相關部門的分析是正確的。我冒昧地根據'tidyverse'軟件包自己創建一些代碼,從而產生更接近原始發表的論文的結果。 – FilipeTeixeira
嗯這太糟糕了,他們沒有解決它。 CRAN軟件包的下載量爲7k,但不應該以目前的形式真正使用。也許你可以在這裏鏈接到你的算法工作版本(如果它在github上)那些搜索答案的人? – gfgm
我把它作爲一個包的一部分,我一直在開發其他東西,可以在這裏找到https://github.com/FilipeamTeixeira/skynet。但是,您可以將其作爲單獨的R文件在那裏調用disparityfilter.R。這是一個相當簡單的實現,但到目前爲止它達到了目的,並且與原始論文的結果相匹配。 – FilipeTeixeira