построить таблицу границ сети из разреженной таблицы - PullRequest
3 голосов
/ 22 сентября 2019

Я не знаю точно, как это объяснить, но ...

У меня есть разреженная таблица, где каждая группа представляет уровень.Столбцы упорядочены, это означает, что нисходящий (левый) столбец представляет дочерний узел, а восходящий (правый) узел представляет родительский узел.
Я бы хотел таблицу из двух столбцов, где 1-й столбец является родительским узлом, а2-й дочерний узел.Если возможно, 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 Ответ

1 голос
/ 23 сентября 2019

Это дает вам 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

Первая часть - это исправление заказа.Ожидаемый результат показывает, что 1-й столбец является дочерним по отношению к 4-му столбцу.Оператор lapply() в основном проходит по data.frame и укладывает данные в стек.

Это 90% пути, потому что ответ не согласуется с ожидаемым результатом для длин.Я думаю, что это правильно, но я могу ошибаться.

Наконец, и я не очень хорош с igraph, вы можете найти дополнительную информацию, выполнив:

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

igraph plot

...