基于相同的逗号分隔文本列重新分配邻接矩阵值

时间:2015-08-11 00:09:55

标签: r

我的数据Dat.1有一个逗号分隔的文本列c.2,看起来像

c.1     c.2
A       IN, CA, IL, NY
B       NJ, IN,AR
C       DC, NY
D       TX, AR, IN

我使用c.1创建一个空的邻接矩阵Aij

    A   B   C   D
A   0   0   0   0
B   0   0   0   0   
C   0   0   0   0
D   0   0   0   0

我想在逗号分隔列中搜索类似文本,c.2如果逗号分隔文本相同,则将我的邻接矩阵Aij重新分配给1。例如,在Dat.1中,“IN”出现在列c.1的A,B和D中,我将在Aij中重新分配AB,AD为1.类似地,“NY”在A中,C和I将分配另一个AC = 1。 “AR”在B和D中,我将指定BD = 1。然后我将添加值,我的新矩阵将是,

    A   B   C   D
A   0   1   1   1
B   1   0   0   1   
C   1   0   0   0
D   1   1   0   0   

如何阅读公共文本并重新分配我的邻接矩阵,而不将列c.2分成许多子列?

1 个答案:

答案 0 :(得分:0)

您必须在某个时候将c.2分开,以便比较这些值。否则你可以尝试做一些正则表达式技巧,但我怀疑它会更快,然后你必须担心逃避你的文本是正则表达式安全。

我确定有很多方法可以做到这一点(可能有一些内置的软件包编码了更快的方法),但这个解决方案的关键是基础R combn函数。

# recreate your dataframe
x <- data.frame(c.1=LETTERS[1:4],
                c.2=c('IN, CA, IL, NY', 'NJ, IN,AR', 'DC, NY', 'TX, AR, IN'),
                stringsAsFactors=F)

这里我们将c2列拆分为列表而不是数据帧,因为每行中的条目数不相同

# split up the comma values
bits <- strsplit(x$c.2, ', ?')

构造一个0的矩阵来保存你的邻接矩阵:

adj <- matrix(0, nrow=nrow(x), ncol=nrow(x), dimnames=list(x$c.1, x$c.1))

首先,要认识到你的邻接矩阵是对称的,即如果(B和A)有1个共同的元素,那么(A和B)也是如此。所以我们只需要计算矩阵的上半部分或下半部分的公共分量数,然后就可以反映它。

关键是combn(1:4, m=2, FUNCTION)。首先尝试combn(1:4, m=2),你会看到它产生数字1:4组合的矩阵,即一个矩阵,所有坐标都进入邻接矩阵(不包括对角线)。您可以改为执行expand.grid(1:4, 1:4)之类的操作,但这将包括长度为2的1:4的排列,即它包括(第1行,第3列)和第3行我们之前确定的第1列,无论如何都具有相同的值。所以我们使用combn只生成坐标到邻接矩阵的上半部分(或下半部分)。

然后,对于FUN,我们只需在intersect上使用bits查看A列中有多少元素。

最后我们使用adj[lower.tri(adj, diag=F)]将值分配给邻接矩阵的下半部分(<-按列分配,我们的坐标是按行的,所以我们使用下半部分而不是上半部分分配给:)

adj[lower.tri(adj, diag=F)] <-
  combn(1:nrow(x), m=2, function (coords) {
    length(intersect(bits[[coords[1]]], bits[[coords[2]]]))
  })

然后最后我们使用下半部分值填充矩阵的上半部分(t(adj)是一些奇特的基础,因为再次按列分配)。

adj[upper.tri(adj)] <- t(adj)[upper.tri(adj)]
> adj
  A B C D
A 0 1 1 1
B 1 0 0 2
C 1 0 0 0
D 1 2 0 0

所有解释都是一个很长的答案,但实际上它只有3行:

adj <- matrix(0, nrow=nrow(x), ncol=nrow(x), dimnames=list(x$c.1, x$c.1)
adj[lower.tri(adj, diag=F)] <-
  combn(1:nrow(x), m=2, function (coords) {
    length(intersect(bits[[coords[1]]], bits[[coords[2]]]))
  })
adj[upper.tri(adj)] <- t(adj)[upper.tri(adj)]
相关问题