首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于相同逗号分隔文本列的邻接矩阵值重新分配

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

Stack Overflow用户
提问于 2015-08-11 00:09:55
回答 1查看 132关注 0票数 0

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

代码语言:javascript
运行
复制
c.1     c.2
A       IN, CA, IL, NY
B       NJ, IN,AR
C       DC, NY
D       TX, AR, IN

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

代码语言:javascript
运行
复制
    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用1重新分配我的邻接矩阵Aij。例如,在数据1中,c.1列的A、B和D中有“in”,我将在Aij中用1重新分配AB、AD。类似地,“NY”在A中,C和我将分配另一个AC=1。“AR”在B和D中,我将赋值给BD=1,然后我将添加值,我的新矩阵看起来就像,

代码语言:javascript
运行
复制
    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列拆分为多个子列?

EN

Stack Overflow用户

回答已采纳

发布于 2015-08-11 00:56:27

您确实需要在某个时候分离c.2,这样您就可以比较这些值。否则,您可以尝试一些正则表达式技巧,但我怀疑这会更快,然后您必须担心转义您的文本,以使正则表达式安全。

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

代码语言:javascript
运行
复制
# 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列拆分为一个列表,而不是一个数据格式,因为每行中的条目数并不相同。

代码语言:javascript
运行
复制
# split up the comma values
bits <- strsplit(x$c.2, ', ?')

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

代码语言:javascript
运行
复制
adj <- matrix(0, nrow=nrow(x), ncol=nrow(x), dimnames=list(x$c.1, x$c.1))

首先,要认识到你的邻接矩阵是对称的,如果(B和A)有一个共同的元素,那么(A和B)也是一样的。因此,我们只需要计算矩阵的上半部分或下半部分的公共分量数,然后就可以对其进行镜像。

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

然后,通过在FUN上使用intersect,我们可以简单地看到A列中有多少元素在B列中。

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

代码语言:javascript
运行
复制
adj[lower.tri(adj, diag=F)] <-
  combn(1:nrow(x), m=2, function (coords) {
    length(intersect(bits[[coords[1]]], bits[[coords[2]]]))
  })

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

代码语言:javascript
运行
复制
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行:

代码语言:javascript
运行
复制
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)]
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31931129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档