2016-11-03 15 views
0

私はさまざまな属性を持つエッジリスト(FromID/ToID)からなるデータフレームを持っています。チェーン内のすべてのノードの累積値の計算R

FromID ToID from_median degree since_0001 total_saved 
0002 0001 10 1 30 
0003 0001 20 1 40 
0004 0002 10 2 70 
0004 0003 10 2 70 
0005 0003 33 2 112 
0006 0004 26 3 129 
0007 0004 14 3 148 
0008 0005 22 3 150 
0009 0005 14 3 157 
0010 0007 15 4 178 
0011 0007 28 4 184 
0011 0008 28 4 184 
0012 0008 12 4 188 
0013 0011 30 5 220 
0014 0012 12 5 207 

df $ degreeは、最初のdf $ ToID(0001)からのdf $ FromIDの距離(度)です。

df $ total_savedは、チェーン内の各IDのdf $ from_median + df $ from_medianの値である必要があります。 FromID 0014は等しくなければならない99:0001 - > 0003 - > 0005 - > 0008 - > 0012 - > 0014 == 20 + 33 + 22 + 12 + Iが単に

df$total_saved <- df$from_median 
とtotal_saved $ dfを移入12

その後、forelse()とベクトル化アプローチ(FromIDとTOIDを一致させるために%in%またはmatch()を使用する)forループのさまざまな組み合わせを試してみましたが、正しいdf $ total_saved値は2度までしか得られません。

どのような考えにも大変感謝しています。 多くのお礼ありがとうございます

+0

FromIdが複製される場合はどうなりますか?たとえば0011の場合0011に進み、0007または0008に行く場合は? – User2321

+0

重複しないようにしておくと、重複する必要はありません。 – pax10t

答えて

1

あなたの質問は完全には解決できませんが、私は解決策を見つけようとします。私は、FromID TOidの下にあるすべてのパスの合計長さを見たいと思っていました。 まず、あるポイントから別のポイントに移動できるかどうかにかかわらず、行列を作成します。次に、全体の次数を求めます。 ここにコード:

require("data.table") 
require("igraph") 
require("matrixStats") 

test <- data.table(FromID = as.character(c(2,3,4,4,5,6,7,8,9,10,11,11,12,13,14)), 
        ToID = as.character(c(1,1,2,3,3,4,4,5,5,7,7,8,8,11,12)), 
        degree = c(10,20,10,10,33,26,14,22,14,15,28,28,12,30,12)) 

igraph <- make_graph(t(test[, .(FromID, ToID)])) 
E(igraph)$weight <- test$degree 
distances <- distances(igraph, mode = "out") 
distances[!is.infinite(distances)] <- 1 
distances[is.infinite(distances)] <- 0 

# Find the longest chain from each node 
chain_dist <- rowMaxs(distances[test$FromID,]) 
names(chain_dist) <- test$FromID 
# Function to find the total length 

FindTotalLength <- function(x){ 
    dist_to <- distances[test$ToID[x],, drop =F] 
    names <- c(test$FromID[x], colnames(dist_to)[dist_to == 1]) 
    return(sum(test[FromID %in% names & ToID %in% names, degree])) 
} 

# Now we got allt he distances now we have to make sure that the first edge will be to ToID 
test[,total_saved := sapply(1 : length(FromID), function(x) FindTotalLength(x))] 
> test 
    FromID ToID degree total_saved 
1:  2 1  10   10 
2:  3 1  20   20 
3:  4 2  10   20 
4:  4 3  10   30 
5:  5 3  33   53 
6:  6 4  26   76 
7:  7 4  14   64 
8:  8 5  22   75 
9:  9 5  14   67 
10:  10 7  15   79 
11:  11 7  28   92 
12:  11 8  28   103 
13:  12 8  12   87 
14:  13 11  30   205 
15:  14 12  12   99 
+0

ありがとう!問題を言葉遣いするのが難しいと感じましたが、あなたは正しい意味を持っています。 igraphの解決策を考えていたはずです。これは上のダミーデータテーブルで完全に動作します。唯一の問題は、私が持っている実際のデータテーブルが1000行以上あることです!is.infiniteコマンドを実行すると、比較的遅いコンピュータがフリーズします!代替アプローチがあるかどうかわかりません – pax10t