Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Je cherche un moyen de prendre un sous-ensemble d'une table de données qui utilise uniquement les lignes correspondant à une condition spécifiée et de soustraire la moyenne de ces lignes d'une colonne.
Par exemple, en utilisant l'ensemble de données Big Class, disons que je souhaite créer une nouvelle colonne affichant "Différence de taille entre cet élève et la moyenne des 14 ans du même sexe."
La façon dont je sais comment procéder consiste à ajouter un deuxième tableau, en utilisant Tableaux -> Résumé -> Statistiques : moyenne (taille), groupe : sexe, sous-groupe : âge. Ensuite, je peux Tableau -> Mise à jour : Big Class By (sex), Match columns : sex = sex, et cela ajoutera plusieurs colonnes pour Mean (height, [age]). Ensuite, je peux créer une nouvelle colonne "Hauteur Delta vs 14 ans du même sexe" qui est : hauteur - : Moyenne (hauteur, 14).
Ma question : existe-t-il un moyen de se passer de la création d'une table supplémentaire et d'une colonne supplémentaire (par exemple "Mean(height, 14)") ? Il semble que Col Mean(x, byVar) soit sur le point de fournir cette fonctionnalité, mais il lui manque la fonctionnalité permettant de sélectionner un groupe différent ; par exemple, je pourrais utiliser :height - Col Mean(:height, :age, :sex) pour trouver le delta entre l'élève X et l'élève moyen de son sexe et de sa taille, mais je ne sais pas s'il existe un moyen de spécifier dans Col Mean, je souhaite considérer uniquement les lignes avec age=14, plutôt que d'utiliser la valeur d'âge associée à cette ligne.
Je fais ce type de normalisation très fréquemment, donc tout ce qui la rendrait plus rapide et plus facile serait énormément apprécié !
Mélange et nettoyage des donnéesRe : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Beau! Merci!!!
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Salut @MarkJSchwab ,
Oui, je peux voir à quel point l'emballage de cela dans des conditions pourrait ne pas être idéal dans de nombreux cas. Voici une modification à @brady_brady La solution de qui devrait fonctionner (tableau ci-joint) :

testVal = :sex;
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 & :sex == testVal )] );
Dans ce cas, nous récupérons la valeur de :sex pour la ligne actuelle, l'enregistrons dans une variable, testVal. Ensuite, lorsque nous évaluons la fonction de centrage, nous pouvons tester l’utilisation de cette valeur dans la fonction get rowswhere().
Voici le tableau avec une colonne contenant uniquement les lignes sélectionnées par cette fonction Get Rows Where() :

Comme vous pouvez le constater, toutes les lignes utilisent l'âge de 14 ans comme sous-ensemble, mais le sous-ensemble de sexe est déterminé par les valeurs actuelles du sexe dans la ligne. Doit être facilement adapté à différents niveaux de complexité.
@julien
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Il vous suffit d'élargir la formule pour gérer à la fois les hommes et les femmes.
If( :sex == "F",
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )] ),
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 & :sex == "M" )] )
)
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Salut @julien Merci encore pour votre aide!
Un dernier problème : idéalement, j'aimerais que l'âge moyen des filles de 14 ans soit soustrait des filles et l'âge moyen des garçons de 14 ans soustrait des garçons. (Dans votre exemple, vous soustrayez l'âge des filles de 14 ans aux garçons et aux filles.)
(Je me rends compte que dans ce cas précis avec juste M/F, il serait facile d'utiliser un conditionnel et de dire "Si :sex == 'F' alors utilisez cette formule, si :sex == 'M' alors modifiez la formule pour disons {mean(:height[(:height << get datatable) << get rowswhere( :age == 14 & :sex == "M" )])}" mais dans mes cas d'utilisation plus généraux, je peux avoir un un grand nombre de groupes et de conditions imbriquées deviendraient lourds.)
Existe-t-il un moyen simple d'y parvenir ?
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Salut @MarkJSchwab ,
Il semble que << Freq a été ajouté comme argument facultatif dans JMP 15, donc pour les versions antérieures de JMP, vous devrez faire autre chose.
Voici une solution de l'assistant jmp @brady_brady :
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 )] )

Cela vaut la peine de prendre un moment pour déballer cette formule, car je parie qu'il existe certaines méthodes que vous trouverez utiles à utiliser plus tard.
(:height << get datatable) << get rows where( :age == 14 )
renverra la matrice des entrées de ligne dans laquelle :age==14. Il est important de noter que vous pouvez modifier la fonction get rowswhere() pour qu'elle corresponde à la recherche que vous souhaitez, y compris la deuxième demande, je crois, que vous avez d'inclure une autre variable. Par exemple:
(:height << get datatable) << get rows where( :age == 14 & :sex == "F"

Maintenant que nous disposons d'une matrice de lignes qui correspondent à votre condition, Brady utilise cette matrice pour indiquer :height.
height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )]

Cela renverra la matrice des valeurs de :height pour chacune de ces lignes, dans ce cas, les tailles des étudiantes de 14 ans : [61, 62, 65, 63, 62]
Enfin, la fonction Mean() est enroulée autour de cette matrice, qui renvoie la moyenne dont vous avez besoin pour calculer votre variable centrée :
mean(:height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )])

Cette solution est plus flexible, tolérante aux données manquantes et fonctionne pour les versions antérieures de jmp, donc dans l'ensemble, c'est une meilleure solution, je pense. Merci, @brady_brady !
@julien
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Salut @julien , Merci pour la suggestion. Malheureusement, quand je colle cette formule exacte
Col Mean( :height, <<FREQ></FREQ>
dans ma grande classe, il renvoie 62,55 (c'est-à-dire la moyenne globale sans sélection de l'âge = 14) au lieu de la valeur correcte que vous voyez de 64,166.
Je peux même télécharger votre pièce jointe, et les valeurs appropriées apparaissent dans la colonne « Centré par rapport à la moyenne à l'âge == 14 ». Mais si je crée une nouvelle colonne dans ce tableau avec exactement la même formule, elle renvoie des valeurs différentes (affichant la [hauteur] - [hauteur moyenne globale], au lieu d'afficher correctement [hauteur] - [hauteur moyenne de 14 ans]).
J'utilise JMP Pro 14.3.0. Avez-vous des idées sur la façon dont je peux faire en sorte que mon résultat corresponde au vôtre ?
Et encore une question, sur votre feuille si vous ajoutez un byVar supplémentaire de :sex (pour la formule totale ":height - (Col Mean( :height, :sex, <Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?
Salut @MarkJSchwab ,
Il existe un moyen simple de le faire en utilisant Col Mean() qui n'est pas évident tant que vous ne le voyez pas. Col Mean() prend un argument de colonne Fréquence :

Habituellement, c'est lorsque vous devez pondérer à l'aide d'une autre colonne. Mais, dans votre exemple, et si nous pouvions pondérer les valeurs de Age==14 comme 1 et toutes les autres valeurs comme 0 ? Cela nous donnerait une moyenne uniquement pour les individus dont Age==14. On peut le faire directement dans la formule :
Col Mean( :height, <<FREQ></FREQ>

Cela reviendra :

Maintenant, pour votre question spécifique, centrée par rapport à cette moyenne spécifique depuis la hauteur, nous pouvons l'intégrer dans la formule de la manière habituelle :
:height - (Col Mean( :height, <<FREQ></FREQ>


J'espère que ça aide!
@julien
Re : Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données ?Salut MarkJSchwab !
Bien sûr, il existe un moyen de faire ce que vous souhaitez.JSL vous libérera !
J'ai écrit un script simple qui utilise principalement la capacité de JSL pour écrire un script pour vous.Essayez-le :
// Title: Bigclass Normalization Script for JMP User Community discussion
// Purpose: Demonstrate how to write a very basic script to do "normalizations"
Names Default To Here( 1 );
Bigclass_dt = Open( "$SAMPLE_DATA\Big Class.jmp" );
BigclassSummary_dt = bigclass_dt << Summary( Group( :age, :sex ), Mean( :height ) );
BigclassSummary_dt << Select Where( :Age != 14 ) << Delete Rows;
Bigclass_dt << Join(
With( BigclassSummary_dt ),
Select( :name, :age, :sex, :height ),
SelectWith( :Name( "Mean(height)" ) ),
By Matching Columns( :sex = :sex ),
Drop multiples( 0, 0 ),
Include Nonmatches( 0, 0 ),
Preserve main table order( 1 ),
Output Table( "NormedBigclass by AgeGender" )
);
BigclassJoin_dt = Data Table( "NormedBigclass by AgeGender" ) << New Column( "Normalized",
numeric,
continuous,
Formula( :Name( "height" ) - :Name( "Mean(height)" ) ),
evalFormula
);
Close( BigclassSummary_dt, NoSave );
J'ai créé un tableau récapitulatif séparé, puis je l'ai fermé, mais vous n'êtes pas obligé de procéder de cette façon.
Il existe bien sûr des moyens plus sophistiqués d'écrire un script comme celui-ci, d'autant plus que toutes les clauses "where" sont codées en dur et que vous pouvez rencontrer des problèmes avec ce script si votre table de données est volumineuse, mais, même quand même, JSL sera votre chemin vers la productivité.Il existe plusieurs excellentes ressources pour apprendre le JSL !
Bonne chance!