从非常大的边缘列表快速计算单向,双向链路的数量

Jib*_*ril 2 r graph-theory

我有一个4 GB的文件,其中有大约20亿个有向边,格式为User1 FOLLOWS User 2,如下所示.

User1       User2
7           37
5           24
7           8383932
24          1
3           8538
37          7

DF = structure(list(User1 = c(7L, 5L, 7L, 24L, 3L, 37L), User2 = c(37L, 
24L, 8383932L, 1L, 8538L, 7L)), .Names = c("User1", "User2"), row.names = c(NA, 
-6L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

等等.我希望能够有效地获得以下结果

User        NumberFollowers        NumberFriends
1           1                      0
7           1                      1
24          1                      0
37          1                      1
8383932     1                      0
8538        1                      0
5           0                      0
3           0                      0
Run Code Online (Sandbox Code Playgroud)

等等,其中NumberFollowers是带有链接的"User1"的数量,NumberFriends是他们也相互关注的追随者的数量.

我目前正在尝试使用

aggregate()
Run Code Online (Sandbox Code Playgroud)

然而,它似乎忽略了用户5和用户3没有朋友或关注者的情况,但他们自己跟随人.

我宁愿不必遍历整个事情,因为我将拥有多少边缘.

有没有任何好的,有效的方式来相对快速和无痛地做到这一点?

谢谢!

Fra*_*ank 5

这是一种方式:

library(data.table)
setDT(DT)

res0 <- rbind(
  DT[, .N, by=.(user=User2)][, lab := "followers"],
  DT[.(User2, User1), on=names(DT), nomatch=0][, .N, by=.(user=User2)][, lab := "friends"]
)[, dcast(.SD, user ~ lab, value.var = "N", fill = 0L)]

      user followers friends
1:       1         1       0
2:       7         1       1
3:      24         1       0
4:      37         1       1
5:    8538         1       0
6: 8383932         1       0
Run Code Online (Sandbox Code Playgroud)

这排除了没有粉丝的用户,但如果需要,可以很容易地添加回来.

DT本身列出了粉丝; 并DT[.(User2, User1), on=names(DT), nomatch=0]列出朋友.

这几乎是以表格格式对这些数据做出的限制.任何更漂亮的东西,你真的想要一个图表.请参阅igraph包.


各种说明:

  • 语法DT[i,j,by]意味着子集使用i; 分组by; 并做j.见?data.table.
  • 任务可以链接为DT[...][...].
  • := 是分配给列的特殊符号.
  • .N是计算组中行数的特殊变量.见?.N.
  • on=nomatch=使用时的辅助参数i中的"加盟"也?data.table.
  • dcast是一个帮助函数,用于从长格式转换为宽格式.见?dcast.