créer un nouvel identifiant pour gérer les relations multiples à multiples*Mise à jour
Désolé, je devrais être plus clair sur la question. Les données que j'ai actuellement ressemble à:
e-mail d'identification
1 un
1 b
2 un
2c
3 j
Nous pouvons voir que l'identifiant 1 2 et l'e-mail abc sont en fait la même personne car les informations se chevauchent.
Ce que j'essaie de faire ici, c'est de créer une table de correspondance avec une nouvelle clé que je peux utiliser pour faire correspondre la table d'origine afin d'identifier ceux qui se chevauchent sont en fait la même personne :
newID identifiant/e-mail
111 1
111 2
111 un
111b
111 c
222 j
Le newID n'a pas besoin d'être sous une forme spécifique, il peut même être égal à l'identifiant d'origine, tant que nous pouvons l'utiliser pour identifier une "personne unique".
-------------------------------------
Salut, j'ai des données avec 2 colonnes, l'une est l'identifiant individuel et l'autre est l'e-mail. Le problème avec ces données est que la relation entre l'identifiant individuel et l'e-mail est multiple à multiple, ce qui signifie qu'un identifiant individuel peut avoir plusieurs e-mails et qu'un e-mail peut avoir plusieurs identifiants individuels. Ainsi, j'aurais besoin de créer une table de mappage d'un nouvel identifiant unique à tous les identifiants/e-mails individuels, qui spécifie que ces identifiants ou e-mails individuels, en cas de chevauchement, sont en fait la même personne. Je ne pouvais pas vraiment penser à un moyen de le faire sans script. Quelqu'un pourrait-il aider? Merci!
Fusion et nettoyage des donnéesIngénierie de la qualité et des procédésRe : créer un nouvel identifiant pour gérer les relations multiples à multiplesMerci beaucoup Jarmo ! Ça marche!!Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJ'ai mal lu/compris comment vous vouliez gérer les valeurs manquantes. Vous voulez une valeur unique pour chacun d'eux, n'est-ce pas ? Comme les valeurs manquantes sont gérées en dernier, vous pouvez simplement remplacer les dernières lignes après //handle missing avec le script ci-dessous :
//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">Re : créer un nouvel identifiant pour gérer les relations multiples à multiples</LINGO-SUB><LINGO-BODY id="lingo-body-366610" slang="en-US" mode="NONE"><P>Salut Jarmo, le résultat semble être le même que le précédent, comme capture d'écran ci-jointe. Le "newid1" est celui qui utilise le script précédent, et le "newid" est celui qui utilise votre dernier script, qui, comme le précédent, a attribué à ces différents identifiants individuels avec un e-mail vide le même newid "750". Pourriez-vous s'il-vous-plaît vérifier? Merci!</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">Re : créer un nouvel identifiant pour gérer les relations multiples à multiples</LINGO-SUB><LINGO-BODY id="lingo-body-366510" slang="en-US" mode="NONE"><P>Impossible de reproduire vos résultats (vous avez très probablement des identifiants individuels différents sur celui commençant par 308....)</P><P> </P><P>Le résultat semble-t-il correct ?</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
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesSalut Jarmo, ci-dessous est un exemple. vous pouvez voir que de nombreuses lignes contenant des e-mails vides sont toutes regroupées sous newid 5. Si l'identifiant individuel ne chevauche pas d'autres groupes, ceux qui n'ont pas d'e-mail doivent chacun avoir leur propre nouvel identifiant. Merci!

Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesComment doivent-ils être manipulés ? Il s'agit très probablement d'une ou deux déclarations if.
Un petit exemple de jeu de données avec des réponses correctes pourrait aider.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesSalut Jarmo, j'ai oublié de mentionner que dans la colonne e-mail, il y a des lignes ayant des cellules vides, ce qui signifie que certains ID individuels n'ont rien rempli sous la colonne e-mail. J'ai trouvé que le script actuel considérera tous les identifiants individuels n'ayant pas d'e-mail comme le même nouvel identifiant. pourriez-vous aider à ajuster le script pour éviter ce genre de situation ? Merci!Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesMerci beaucoup Jarmo ! Ça marche!! J'apprécie vraiment votre aide.Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesEt selon la façon dont vous obtenez la table de données, vous pouvez la référencer directement :
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; ");et ainsi de suite
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesdt = current data table();
ou
dt = Data table("Name of table here")Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesMerci Jarmo ! Comment puis-je changer le dt en ma table de données actuelle sans créer la nouvelle table avec les échantillons que vous avez mis?Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJ'ai un peu modifié le script (changé la récursivité en boucle while car la récursivité peut être un peu difficile à comprendre de temps en temps). Les noms de colonnes ont également été modifiés.
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];
);
);
);Vous avez vu avoir supprimé les références dt de votre version modifiée, cela pourrait causer des problèmes.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesMerci beaucoup Jarmo ! Ce résultat de votre script est exactement ce dont j'ai besoin. Je ne suis pas familier avec le script, donc juste une question suivante sur la façon de l'appliquer sur ma table actuelle. les deux noms de colonne sont "Individualid" et "Email_HASHED", j'ai collé le script modifié ci-dessous dans ma table mais il a montré une erreur. pourriez-vous déboguer pour moi? Merci!
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);
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesMerci Dale ! Oui, c'est un point valable, mais pour cette analyse de rentabilisation, nous avons décidé de traiter les personnes ayant le même e-mail comme une seule personne afin de calculer la séquence de leur autre comportement.Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesCela semble définitivement une façon un peu étrange de le faire, car @dale_lehman a dit. Vous pouvez scripter cela au moins avec la récursivité. Vous trouverez ci-dessous un exemple de code très désordonné qui semblait fonctionner au moins avec mes données d'exemple (si j'ai bien compris l'idée):
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);J'ai ajouté des options Select Where et Waits supplémentaires dans la fonction pour essayer de montrer ce qui se passe.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJe pense que vous avez besoin de quelqu'un pour écrire ce script.J'ai essayé plusieurs façons, mais je n'arrive pas à obtenir quoi que ce soit qui fonctionne - et il y a eu tellement d'étapes que cela ne semble pas en valoir la peine.Je trouve la situation un peu étrange cependant - vous avez des personnes avec plusieurs adresses e-mail, comme c'est courant, mais vous avez également plusieurs personnes utilisant la même adresse e-mail, ce qui arrive également.Cependant, vous souhaitez identifier des personnes uniques - je ne vois pas pourquoi vous diriez que deux personnes partageant la même adresse email ne sont en réalité qu'une seule personne ?Dans votre exemple, vous semblez vouloir exclure l'ID de personne n° 2 en tant que personne unique, car ils partagent des adresses e-mail avec d'autres.Mais pourquoi cela voudrait-il dire qu'ils ne sont pas une personne unique ?Est-il possible que vous compliquiez ce problème plus que nécessaire ?Mon inclination serait de me concentrer uniquement sur les identifiants uniques, puis de vouloir la liste des adresses e-mail qui leur sont associées, une simple fonction de tabulation.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesSalut Dale ! J'ai mis à jour les informations dans le message d'origine. Veuillez vérifier, merci!Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesSalut Paul! J'ai mis à jour les informations dans le message d'origine. Veuillez vérifier, merci!Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJe pense que vous pouvez le faire en tabulant (comme dans mon exemple), puis en créant une table de données, puis en créant une colonne de concaténation (plusieurs concaténations si vous souhaitez insérer le ", ").
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJe pense que ce qu'il faut, c'est un tableau du type :
à partir d'un tableau qui ressemble à ceci :
| IDENTIFIANT | e-mail |
| dix | ... |
| 11 | ... |
| 12 | .. |
| 15 | .. |
| 16 | .. |
| 17 | .. |
| 18 | .. |
Mais je ne sais pas comment vous sauriez quels identifiants et quels e-mails appartiennent à la même personne, c'est donc sur quoi portait ma question.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesJe ne pense pas comprendre ce que tu veux.Il semble que vous pourriez simplement concaténer les deux colonnes et vous auriez une combinaison personne/e-mail unique pour chaque observation.Si vous voulez que chaque personne ou chaque e-mail soit dans sa propre ligne, utilisez simplement Tabuler.J'ai joint un exemple de tableau montrant le mappage multiple-multiple, avec une tabulation ainsi qu'une nouvelle colonne avec un identifiant unique.Vous pouvez peut-être utiliser cet exemple pour nous dire ce que vous voulez.
Re : créer un nouvel identifiant pour gérer les relations multiples à multiplesAlors, où obtiendriez-vous les informations qui vous indiquent quel numéro unique est une personne unique ? Sur la base de ces deux colonnes que vous décrivez, vous n'avez pas d'autre choix que de faire de l'une des colonnes l'identifiant unique et de mapper l'autre dessus. Peut-être poster des exemples de données?