首页 > 解决方案 > 将链接观察的长表转换为宽邻接矩阵

问题描述

我面临着一个我无法解决的挑战。我有一个观察 x_i 列表(尺寸很大,大约 30k)和一个观察 y_j 列表(也很大)。x_i 和 y_i 是相同单位的 id(比如公司)。

我有一个包含两列链接的数据框x_iy_j如果它们出现在同一行,则表示它们已连接。我想要的是把这个网络转换成一个大矩阵M(unique(union(x, y)))如果这两家公司是连接的,那么它的值就是 1。

这是一个小尺寸的例子:

x1 x2
x3 x6
x4 x5
x1 x5

我想要的是一个矩阵:

0 1 0 0 1 0
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0

现在,我能想到的唯一解决方案是在初始数据帧中结合搜索的双循环:

list_firm = union(as.vector(df[1]), as.vector(df[2]))
list_firm <- sort(list_firm[[1]])
list_firm <- unique(list_firm)
M <- Matrix(nrow = length(list_firm), ncol = length(list_firm))

for (i in list_firm) {
    for (j in list_firm) {
        M[i, j] = !is.null(which(df$col1 == i & df$col2 == j))
    }
}

df两列数据框在哪里。这显然太长了,无法运行。

有什么建议吗?这将非常受欢迎

标签: rmatrix

解决方案


我们将列转换为factor指定levelsunique两列的元素并获得频率table

lvls <- sort(unique(unlist(df)))
df[] <- lapply(df, factor, levels = lvls)
table(df)
#  col2
#col1 x1 x2 x3 x4 x5 x6
#  x1  0  1  0  0  1  0
#  x2  0  0  0  0  0  0
#  x3  0  0  0  0  0  1
#  x4  0  0  0  0  1  0
#  x5  0  0  0  0  0  0
#  x6  0  0  0  0  0  0

数据

df <- structure(list(col1 = c("x1", "x3", "x4", "x1"), col2 = c("x2", 
 "x6", "x5", "x5")), class = "data.frame", row.names = c(NA, -4L
 ))

推荐阅读