【问题标题】:R or postgres SQL code : How to identify all connected values in a table to identify unique networksR 或 postgres SQL 代码:如何识别表中的所有连接值以识别唯一网络
【发布时间】:2020-03-27 16:23:56
【问题描述】:

我遇到了一个有点类似于社交网络的问题。我需要识别一个朋友网络中的所有候选人,并给该朋友网络一个网络名称或编号。我必须在 SQL(postgres) 或 R 中写这个

"Createdcolumn(network)") 是我最后需要创建的。 Column1 和 Column2 已经在我的数据中

S.no/lineno        Column1      Column2    Createdcolumn(network)
   1                Peet         Jackson        1
   2                Jason        Filip          2
   3                Luke         Filip          2
   4                Jason        Becky          2
   5                Aron         Chris          3
   6                Maron        Cheese         4
   7                Matt         Brooklyn       5
   8                Brooklyn     Federer        5
   9                Ruselle      Federer        5

关于第一个图了解创建列的更多信息:

2、3、4行在网络2中是一起的,因为那是一个朋友圈,逻辑如下:

第 2 行和第 3 行因为 Filip 而连接

第 4 行和第 2 行因为 Jason 而连接

(所以现在所有 2,3 和 4 行实际上都是一个网络,因为它们都以某种方式连接;可能是朋友的朋友,或者朋友的朋友的朋友,或者朋友的朋友的 n 次)

同样7、8、9是一个网络,逻辑如下:

第 7 行和第 8 行是一个网络,因为布鲁克林

因为费德勒,第 8 行和第 9 行是一个网络

(所以现在所有第 7,8 和 9 行实际上是一个网络,因为它们以某种方式连接;可能是朋友的朋友,或者朋友的朋友的朋友,或者朋友的朋友的 n 次)

第 1 行:Peet 和 Jackson 没有其他朋友网络,因此该行本身就是一个网络

第 5 行:Aron 和 Chris 没有其他朋友网络,因此该行本身就是一个网络

现在

S.no/lineno        Column1      Column2    Createdcolumn(network)
   1                Peet         Jackson        1
   2                Jason        Filip          2
   3                Luke         Filip          2
   4                Jason        Becky          2
   5                Aron         Chris          3
   6                Maron        Cheese         4
   7                Matt         Brooklyn       5
   8                Brooklyn     Federer        5
   9                Ruselle      Federer        5
   10               Aron         Ruselle        5 

现在解释图 2 以便更好地理解:

在图 2 中,我在第 10 行添加了“Aron”和“Ruselle”。所以现在第 5 行从网络 3 更改为网络 5,因为它们都已连接:

7 号线和 8 号线因布鲁克林而相连

第 8 行和第 9 行因为费德勒而相连

第 9 行和第 10 行因为 Ruselle 是连通网络

第 5 行和第 10 行是因为 Aron 而连接的网络

(所以现在所有 5、7、8、9 和 10 行实际上都是一个网络,因为它们以某种方式连接)

标注: 1)图2中的网络5也可以重命名为网络“3”,没有问题。拥有一切的主要理念 作为 ONE 网络的一部分将人们联系起来 2) 我的列表不是动态的,不会从图 1 中的列表增长到图 2,所以我只需要一个可以在短期内完成我的工作的解决方案。现在不需要扩展解决方案 3)我的表有相同的两列,但几乎有 40K 唯一名称,所以我不能将任何名称硬编码到我的代码中 4) 名称可以是字母,也可以是字母数字的数字

我尝试使用复杂的全连接和交叉连接,但这很乏味。我读到了 R 上的 igraph 包,这可能是我正在寻找的

不确定我是否清楚地解释了我的问题。如有任何混淆,请见谅*

谢谢

【问题讨论】:

  • 不要为不包含图片而道歉 - 如果可能,不应使用它们。只需将实际数据剪切并粘贴到您的问题中,即可非常更容易理解。
  • 好多了 - 一个有趣的问题。认为它在 sql 中是可行的。你用的是什么数据库?如果它在你的风格中可用,它可能是一个递归 CTE。
  • 它的 postgres SQL。我也许可以在 R 中复制这个逻辑
  • 我已经更新了我对 postgres 语法的回答。您应该更新您的标签以包括 postgres。

标签: sql r recursion social-networking network-analysis


【解决方案1】:

**EDIT - 将其转换为 PostgresSQL 语法

这里是一个解决方案,基于 sql server cte 语法:

首先创建表:

create table net(s int, c1 varchar(20), c2 varchar(20))

下一步用您的数据填充:

insert into net values 
(1,'Peet','Jackson')
,(2,'Jason','Filip')
,(3,'Luke','Filip')
,(4,'Jason','Becky')
,(5,'Aron','Chris')
,(6,'Maron','Cheese')
,(7,'Matt','Brooklyn')
,(8,'Brooklyn','Federer')
,(9,'Ruselle','Federer')
,(10,'Aron','Ruselle')

现在是 CTE:

;with recursive cte as (
    select *, ','||c1||','||c2 as network, s as MaxS from net 
    union all
    select net.*, cte.network||','
    ||case when cte.network like '%'||net.c1||'%' then net.c2 else net.c1 end,net.s
    from net
    join cte on cte.network like '%'||','||net.c1||'%'  or cte.network like '%'||','||net.c2||'%'
    where net.s>cte.MaxS
) 
, groups as (
    select net.*, network, MaxS,
    row_number() over (partition by net.s order by length(network) desc) as longest
    from net
    join cte on cte.network like '%'||','||net.c1||'%'
) 
select s,c1,c2, 
dense_rank() over (order by MaxS) as groupno
from groups where longest=1

结果:

s   c1       c2     groupno
1   Peet     Jackson    1
2   Jason    Filip      2
3   Luke     Filip      2
4   Jason    Becky      2
6   Maron    Cheese     3
7   Matt     Brooklyn   4
8   Brooklyn Federer    4
9   Ruselle  Federer    4
10  Aron     Ruselle    4
5   Aron     Chris      4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2019-05-24
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    相关资源
    最近更新 更多