創建新的 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 來處理多對多關係那麼,您從哪裡獲得信息來告訴您哪個唯一號碼是唯一的人呢? 僅基於您所描述的這兩列,您別無選擇,只能將其中一列設為唯一標識符並將另一列映射到其上。 也許發布一些示例數據?