计算R中链中所有节点的累积值

时间:2016-11-03 10:49:36

标签: r

我有一个包含各种属性的边缘列表(FromID / ToID)的数据框。

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 $ FromID与初始df $ ToID(0001)的距离(以度为单位)。

df $ total_saved应该是df $ from_median +其链中每个ID的df $ from_median值:例如FromID 0014应该等于99:0001 - > 0003 - > 0005 - > 0008 - > 0012 - > 0014 == 20 + 33 + 22 + 12 + 12

我只是用

填充了df $ total_saved
df$total_saved <- df$from_median

然后尝试了for循环,ifelse()和矢量化方法的各种组合(使用%in%或match()来匹配FromID和TOID)没有太多运气,只获得正确的df $ total_saved值最多2度。

任何想法都非常感激。 非常感谢

1 个答案:

答案 0 :(得分: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