创建新的 id 来处理多对多关系*更新
抱歉,我应该更清楚地回答这个问题。 我目前拥有的数据如下所示:
身份证电子邮件
1 个
1b
2个
2c
3天
我们可以看到 id 1 2 和 email abc 实际上是同一个人,因为信息重叠。
我在这里想做的是拿出一个带有新密钥的匹配表,我可以用它来匹配回原始表,以识别那些重叠的表实际上是同一个人:
新ID ID/电子邮件
111 1
111 2
111 一个
111 乙
111c
222天
newID不需要是特定的形式,甚至可以等于原来的id,只要我们能用它来识别“唯一的人”即可。
------------------------------------------------
你好,我有两列数据,一列是个人 ID,一列是电子邮件。 此数据的问题在于个人 ID 和电子邮件之间的关系是多对多的,这意味着一个个人 ID 可以有多个电子邮件,而一封电子邮件可以有多个个人 ID。 因此,我需要创建一个新的唯一 ID 到所有个人 ID/电子邮件的映射表,该表指定这些个人 ID 或电子邮件(如果有重叠)实际上是同一个人。 我真的想不出没有脚本的方法。 有人可以帮忙吗? 谢谢你!
数据混合和清理质量和工艺工程回复:创建新的 id 来处理多对多关系非常感谢贾莫! 有用!!回复:创建新的 id 来处理多对多关系我确实错误地阅读/理解了您想要如何处理缺失值。 您希望他们每个人都有独特的价值,对吗? 由于缺失值是最后处理的,因此您可以使用以下脚本替换 //handlemissing 之后的最后一行:
//handle missings
For Each Row(dt,
If(IsMissing(:newid),
index++;
dt:newId = index;
);
);
</CODE></P></LINGO-BODY><LINGO-SUB id="lingo-sub-366610" slang="en-US" mode="NONE">回复:创建新的 id 来处理多对多关系</LINGO-SUB><LINGO-BODY id="lingo-body-366610" slang="en-US" mode="NONE"><P>嗨,Jarmo,结果似乎与前一个相同,如所附屏幕截图所示。 “newid1”是使用之前脚本的那个,“newid”是使用您最新脚本的那个,与之前的脚本相同,为那些具有空电子邮件的不同个人ID分配了相同的newid“750”。 您能检查一下吗? 谢谢你!</P><P> </P><P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Screen Shot 2021-03-09 at 3.56.12 PM.png" style="width: 143px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="Screen Shot 2021-03-09 at 3.56.12 PM.png" style="width: 143px;"><span class="lia-inline-image-display-wrapper" image-alt="Screen Shot 2021-03-09 at 3.56.12 PM.png" style="width: 143px;"><img src="https://us.v-cdn.net/6038925/uploads/images/31129i40283FF98CA6E0FA/Screen%20Shot%202021-03-09%20at%203.56.12%20PM.png" role="button" title="Screen Shot 2021-03-09 at 3.56.12 PM.png" alt="Screen Shot 2021-03-09 at 3.56.12 PM.png" /></span></SPAN></SPAN></P></LINGO-BODY><LINGO-SUB id="lingo-sub-366510" slang="en-US" mode="NONE">回复:创建新的 id 来处理多对多关系</LINGO-SUB><LINGO-BODY id="lingo-body-366510" slang="en-US" mode="NONE"><P>无法复制您的结果(很可能您在以 308 开头的 ID 上有不同的个人 ID......)</P><P> </P><P>结果看起来正确吗?</P><PRE><CODE class=" language-jsl">Names Default To Here(1);
//https://community.jmp.com/t5/Discussions/create-new-id-to-deal-with-multiple-to-multiple-relationship/m-p/365298#M61470
/*
dt = New Table("Untitled",
Add Rows(20),
Compress File When Saved(1),
New Column("Individualid",
Numeric,
"Continuous",
Format("Best", 12),
Set Values([1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9])
),
New Column("Email_HASHED",
Character,
"Nominal",
Set Values(
{"a", "b", "a", "c", "d", "e", "f", "g", "a", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "b"}
)
)
);
*/
dt = New Table("Untitled",
Add Rows(19),
Compress File When Saved(1),
New Column("Individualid",
Numeric,
"Continuous",
Format("Best", 12),
Set Values(
[139, 100, 229, 301, 308, 284, 682, 136, 586, 256, 122, 711, 629, 116,
152, 443, 301, 695, 311]
)
),
New Column("Email_HASHED",
Character,
"Nominal",
Set Values(
{"A648", "CAA", "E7B", "5B2", "", "237A", "", "FE0", "", "7C21", "",
"920B", "", "D394", "", "2FE1", "", "", ""}
)
)
);
dt << Size Window(500,900);
dt << New Column("newid", numeric, ordinal);
//setup first values before While loop
rowList = [1];
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0];
index = 1;
//looping
While(1,
oldRowList = rowList;
Remove From(emailList, Contains(emailList, ""));
rowList = dt << Get Rows Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED));
//dt << Select Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED)); //for visualization
//wait(1); //for visualization
If(N Items(oldRowList) != N Items(rowList),
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0],
If(All(oldRowList == rowList),
dt:newid[rowList] = index;
newRow = Contains(dt:newid << get as matrix, .);
newRow = 0;
For Each Row(dt,
If(:Email_HASHED != "" & IsMissing(:newId),
newRow = Row();
break();
)
);
If(newRow == 0,
break(),
);
index += 1;
rowList = Matrix(newRow);
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0];
);
);
);
//dt << Clear Select;
//handle missings
index++;
missingRows = dt << Get Rows Where(IsMissing(:newId));
dt:newId[missingRows] = index
回复:创建新的 id 来处理多对多关系你好,Jarmo,下面是一个例子。您可以看到许多具有空电子邮件的行都被分组为 newid 5。 如果 individualID 不与其他组重叠,则那些没有电子邮件的人应该各自拥有自己的 newid。 谢谢你!

回复:创建新的 id 来处理多对多关系应该如何处理? 最有可能的是一两个 if 语句。
具有正确答案的小示例数据集可能会有所帮助。
回复:创建新的 id 来处理多对多关系您好,Jarmo,我忘了提及,在电子邮件列中,有一些行包含空单元格,这意味着某些 individualID 在电子邮件列下没有填充任何内容。 我发现当前脚本会将所有没有电子邮件的个人 id 视为同一个新 id。你能帮忙调整一下脚本以避免这种情况吗? 谢谢你!回复:创建新的 id 来处理多对多关系非常感谢贾莫! 有用!! 非常感谢您的帮助。回复:创建新的 id 来处理多对多关系根据获取数据表的方式,您可以直接引用它:
dt = Open("$SAMPLE_DATA/Big Class.jmp");
dt1 = dt << Subset(All rows);
dt2 = Query(dt, "SELECT name, age, height FROM 'Big Class' WHERE age > 14; ");等等
回复:创建新的 id 来处理多对多关系dt = current data table();
或者
dt = Data table("Name of table here")回复:创建新的 id 来处理多对多关系谢谢贾莫! 如何将 dt 更改为当前数据表,但不使用您放入的示例创建新表?回复:创建新的 id 来处理多对多关系我稍微修改了脚本(将递归更改为 while 循环,因为递归有时可能有点难以理解)。 还更改了列名称。
Names Default To Here(1);
//https://community.jmp.com/t5/Discussions/create-new-id-to-deal-with-multiple-to-multiple-relationship/m-p/365298#M61470
dt = New Table("Untitled",
Add Rows(20),
Compress File When Saved(1),
New Column("Individualid",
Numeric,
"Continuous",
Format("Best", 12),
Set Values([1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9])
),
New Column("Email_HASHED",
Character,
"Nominal",
Set Values(
{"a", "b", "a", "c", "d", "e", "f", "g", "a", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "b"}
)
)
);
dt << Size Window(500,900);
dt << New Column("newid", numeric, ordinal);
//setup first values before While loop
rowList = [1];
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0];
index = 1;
//looping
While(1,
oldRowList = rowList;
rowList = dt << Get Rows Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED));
dt << Select Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED)); //for visualization
wait(1); //for visualization
If(N Items(oldRowList) != N Items(rowList),
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0],
If(All(oldRowList == rowList),
dt:newid[rowList] = index;
newRow = Contains(dt:newid << get as matrix, .);
If(newRow == 0,
break(),
);
index += 1;
rowList = Matrix(newRow);
idList = dt:Individualid[rowList,0];
emailList = dt:Email_HASHED[rowList,0];
);
);
);您发现已从修改版本中删除了 dt 引用,这可能会导致问题。
回复:创建新的 id 来处理多对多关系非常感谢贾莫! 你的脚本的结果正是我所需要的。 我不熟悉脚本,因此只有一个关于如何将其应用到我当前的表上的问题。两个列名称是“Individualid”和“Email_HASHED”,我将下面编辑的脚本粘贴到我的表中,但它显示错误。你能为我调试一下吗? 谢谢你!
New Column("newid", numeric, ordinal);
createIndex = function({tempRows, index},
wait(0.5); //for visualization
idList = Individualid[tempRows,0];
emailList = Email_HASHED[tempRows,0];
tempRowsNew = Get Rows Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED));
Select Where(Contains(idList, :Individualid) | Contains(emailList, :Email_HASHED)); //for visualization
wait(0.5); //for visualization
If(N Items(tempRows) != N Items(tempRowsNew),
ids = Individualid[tempRowsNew,0];
emails = Email_HASHED[tempRowsNew,0];
Recurse(tempRowsNew, index),
If(All(tempRows == tempRowsNew),
newId[tempRowsNew] = index;
newRow = Contains(newId << get as matrix, .);
If(newRow == 0,
Clear Select;
return("done"),
ids = Individualid[newRow,0];
emails = Email_HASHED[newRow,0];
Recurse(matrix(newRow), index + 1);
);
)
);
);
wait(1);
createIndex([1], 1);
回复:创建新的 id 来处理多对多关系谢谢戴尔! 是的,这是一个有效的观点,但对于这个业务案例,我们决定将具有相同电子邮件的人视为一个人,以便计算他们其他行为的顺序。回复:创建新的 id 来处理多对多关系这绝对看起来有点奇怪@dale_lehman说。 您至少可以使用递归来编写此脚本。 下面是非常混乱的示例代码,它似乎至少适用于我的示例数据(如果我正确理解了这个想法):
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(20),
Compress File When Saved(1),
New Column("id",
Numeric,
"Continuous",
Format("Best", 12),
Set Values([1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 8, 9])
),
New Column("email",
Character,
"Nominal",
Set Values(
{"a", "b", "a", "c", "d", "e", "f", "g", "a", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "b"}
)
)
);
dt << Size Window(500,900);
dt << New Column("newid", numeric, ordinal);
createIndex = function({tempRows, index},
wait(0.5); //for visualization
idList = dt:id[tempRows,0];
emailList = dt:email[tempRows,0];
tempRowsNew = dt << Get Rows Where(Contains(idList, :id) | Contains(emailList, :email));
dt << Select Where(Contains(idList, :id) | Contains(emailList, :email)); //for visualization
wait(0.5); //for visualization
If(N Items(tempRows) != N Items(tempRowsNew),
ids = dt:id[tempRowsNew,0];
emails = dt:email[tempRowsNew,0];
Recurse(tempRowsNew, index),
If(All(tempRows == tempRowsNew),
dt:newId[tempRowsNew] = index;
newRow = Contains(dt:newId << get as matrix, .);
If(newRow == 0,
dt << Clear Select;
return("done"),
ids = dt:id[newRow,0];
emails = dt:email[newRow,0];
Recurse(matrix(newRow), index + 1);
);
)
);
);
wait(1);
createIndex([1], 1);我在函数内添加了额外的“选择位置”和“等待”,以尝试显示正在发生的情况。
回复:创建新的 id 来处理多对多关系我认为你需要有人来编写这个脚本。我尝试了多种方法,但似乎没有任何有效的方法 - 而且涉及的步骤太多,似乎不值得。然而,我确实发现这种情况有点奇怪——有人拥有多个电子邮件地址,这很常见,但也有多人使用同一个电子邮件地址,这种情况也会发生。但是,您想要识别独特的人 - 我不明白为什么您会说共享同一电子邮件地址的两个人实际上只是一个人?在您的示例中,您似乎希望将人员 ID #2 作为唯一人员排除,因为他们与其他人共享电子邮件地址。但这为什么意味着他们不是一个独特的人呢?您是否有可能使这个问题变得过于复杂?我的倾向是只关注唯一的 ID,然后想要与它们关联的电子邮件地址列表,这是一个简单的表格函数。
回复:创建新的 id 来处理多对多关系嗨戴尔! 我更新了原始帖子中的信息。 请检查一下,谢谢!回复:创建新的 id 来处理多对多关系嗨保罗! 我更新了原始帖子中的信息。 请检查一下,谢谢!回复:创建新的 id 来处理多对多关系我认为您可以通过制表(如我的示例中),然后制作数据表,然后创建一个列连接(如果您想插入“,”,则可以多个连接)来做到这一点。
回复:创建新的 id 来处理多对多关系我认为需要的是一个像这样的表:
从看起来像这样的表:
| ID | 电子邮件 |
| 10 | ... |
| 11 | ... |
| 12 | .. |
| 15 | .. |
| 16 | .. |
| 17 号 | .. |
| 18 | .. |
但我不清楚你如何知道哪个 ID 和哪个电子邮件属于同一个人,所以这就是我的问题所在。
回复:创建新的 id 来处理多对多关系我想我不明白你想要什么。听起来您只需连接两列即可,每次观察都会有一个独特的人员/电子邮件组合。如果您希望每个人或每封电子邮件都在自己的行中,只需使用制表即可。我附上了一个示例表,显示了多重映射,其中包含一个制表符以及一个具有唯一标识符的新列。也许您可以用这个例子来告诉我们您想要什么。
回复:创建新的 id 来处理多对多关系那么,您从哪里获得信息来告诉您哪个唯一号码是唯一的人呢? 仅基于您所描述的这两列,您别无选择,只能将其中一列设为唯一标识符并将另一列映射到其上。 也许发布一些示例数据?