我有一个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")
等等。我希望能够有效地获得以下结果
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
等等,其中NumberFollowers是带有链接的" User1"的数量,而NumberFriends是他们也相互关注的追随者的数量。
我目前尝试使用
aggregate()
然而,它似乎忽略了用户5和用户3等没有朋友或关注者的情况,但他们自己也会关注人。
我宁愿不必遍历整个事物,因为我将拥有多少边缘。
有没有任何好的,有效的方式来相对快速和无痛地做到这一点?
谢谢!
答案 0 :(得分: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
这排除了没有关注者的用户,但如果需要,可以很容易地添加回来。
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
。