从稀疏表构建网络边缘表

时间:2019-09-22 19:58:19

标签: r networking reshape tidyverse

我不知道该怎么解释,但是...

我有一个稀疏表,其中每个组代表一个级别。这些列是有序的,这意味着下游(左)列表示子节点,上游(右)节点表示父节点。
我想要一个两列表,其中第一列是父节点,第二列是子节点。如果可能的话,在第3列中加上父项的长度(最终节点数的总和)。

遵循示例:

>tt <- tibble(
  ID  = letters[1:8],
  `1` = c( 1, 1, 1, 1, 2, 2, 2, 2),
  `2` = c( 3, 3, 4, 4, 5, 5, 5, 6),
  `3` = c( 7, 7, 8, 9,10,10,11,12)
)
> tt
# A tibble: 8 x 4
  ID      `1`   `2`   `3`
  <chr> <dbl> <dbl> <dbl>
1 a         1     3     7
2 b         1     3     7
3 c         1     4     8
4 d         1     4     9
5 e         2     5    10
6 f         2     5    10
7 g         2     5    11
8 h         2     6    12

>dput(tt)
structure(list(ID = c("a", "b", "c", "d", "e", "f", "g", "h"), 
    `1` = c(1, 1, 1, 1, 2, 2, 2, 2), `2` = c(3, 3, 4, 4, 5, 5, 
    5, 6), `3` = c(7, 7, 8, 9, 10, 10, 11, 12)), row.names = c(NA, 
-8L), class = c("tbl_df", "tbl", "data.frame"))

结果应该是:

>ttt <- tibble(
  parent = c(1,1,2,2,3,4,4, 5, 5, 6, 7,7,8,9,10,10,11,12),
  child  = c(3,4,5,6,7,8,9,10,11,12, letters[1:8]       ),
  length = c(4,4,4,4,2,2,2, 3, 3, 1, 2,2,1,1, 2, 2, 1, 1)
)
>ttt
# A tibble: 18 x 3
   parent child length
    <dbl> <chr>  <dbl>
 1      1 3          4
 2      1 4          4
 3      2 5          4
 4      2 6          4
 5      3 7          2
 6      4 8          2
 7      4 9          2
 8      5 10         3
 9      5 11         3
10      6 12         1
11      7 a          2
12      7 b          2
13      8 c          1
14      9 d          1
15     10 e          2
16     10 f          2
17     11 g          1
18     12 h          1
> dput(ttt)
structure(list(parent = c(1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 
8, 9, 10, 10, 11, 12), child = c("3", "4", "5", "6", "7", "8", 
"9", "10", "11", "12", "a", "b", "c", "d", "e", "f", "g", "h"
), length = c(4, 4, 4, 4, 2, 2, 2, 3, 3, 1, 2, 2, 1, 1, 2, 2, 
1, 1)), row.names = c(NA, -18L), class = c("tbl_df", "tbl", "data.frame"
))

感谢您的帮助。 提前致谢。

1 个答案:

答案 0 :(得分:1)

这可以让您90%地到达目的地:

tt_correct <- tt[, c(2,3,4,1)]

ttt <- do.call(
  rbind,
  lapply(seq_len(length(tt)-1),
       function(i){
         DF <- tt_correct[, c(i, i+1)]
         names(DF) <- c('parent', 'child')
         DF$length <- ave(DF$parent, DF$parent, FUN = length)
         unique(DF)
       }
  )
)

ttt

# A tibble: 18 x 3
   parent child length
    <dbl> <chr>  <dbl>
 1      1 3          4
 2      1 4          4
 3      2 5          4
 4      2 6          4
 5      3 7          2
 6      4 8          2
 7      4 9          2
 8      5 10         3
 9      5 11         3
10      6 12         1
11      7 a          2
12      7 b          2
13      8 c          1
14      9 d          1
15     10 e          2
16     10 f          2
17     11 g          1
18     12 h          1

第一部分是更正顺序。您的预期输出表明第一列是第四列的子级。 lapply()语句主要沿着data.frame并堆叠数据。

这是90%的方法,因为答案与您期望的长度输出不一致。我认为这是正确的,但我可能是错的。

最后,我对igraph并不满意,您可能会发现其他信息:

library(igraph)
plot(graph_from_data_frame(ttt[, 1:2]))

igraph plot