Formule pour soustraire la moyenne d'un sous-ensemble d'une colonne de données?Je recherche un moyen de prendre un sous-ensemble d'une table de données qui n'utilise que des 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 le jeune moyen de 14 ans du même sexe."
La façon dont je sais comment faire est d'ajouter un deuxième tableau, en utilisant Tables -> Résumé -> Statistiques: moyenne (taille), groupe: sexe, sous-groupe: âge. Ensuite, je peux Table -> Update: 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 de même sexe" qui est: hauteur -: Moyenne (hauteur, 14).
Ma question: y a-t-il un moyen de faire avec sans créer une table supplémentaire, et la colonne supplémentaire (par exemple "Moyenne (hauteur, 14)")? Il semble que Col Mean (x, byVar) est proche de fournir cette fonctionnalité, mais n'a pas la fonctionnalité pour 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 leur propre sexe et taille, mais je ne sais pas s'il existe un moyen de spécifier dans Col Signifie que je ne veux considérer que 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é!
Tableau de donnéesRe: 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 à é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 le faire 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 JSL!
Bonne chance!
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 Frequency:

Habituellement, c'est lorsque vous devez pondérer en utilisant une autre colonne. Mais, dans votre exemple, que se passerait-il si nous pouvions pondérer les valeurs de Age == 14 comme 1 et toutes les autres valeurs comme 0? Cela nous donnerait une moyenne des individus pour lesquels Age == 14. Nous pouvons le faire directement dans la formule:
Col Mean( :height, <<FREQ></FREQ>

Cela retournera:

Maintenant, pour votre question spécifique, centrée par rapport à cette moyenne spécifique de la hauteur, nous pouvons l'envelopper 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 @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 totale des colonnes sans sélectionner 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 cette table avec exactement la même formule, elle renvoie des valeurs différentes (montrant 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 ma sortie corresponde à la vôtre?
Et une autre question, sur votre feuille si vous ajoutez une byVar supplémentaire de: sexe (pour la formule totale ": height - (Col Mean (: height,: sex, << Freq (: age == 14)))" fait cela soustraire la taille moyenne des garçons de 14 ans aux garçons et la taille moyenne des filles de 14 ans aux filles?
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é en tant qu'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 il existe certaines méthodes que je parie 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. Surtout, vous pouvez modifier la fonction get rows where () pour qu'elle corresponde à la recherche que vous souhaitez, y compris la deuxième demande que je pense que vous avez d'inclure une autre variable. Par exemple:
(:height << get datatable) << get rows where( :age == 14 & :sex == "F"

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

Cela renverra la matrice des valeurs de: hauteur pour chacune de ces lignes, dans ce cas, les hauteurs 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 plus flexible, tolérante aux données manquantes, et fonctionne pour les versions antérieures de jmp, donc dans l'ensemble 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 encore pour votre aide!
Une dernière ride: idéalement, je voudrais que l'âge moyen des filles de 14 ans soit soustrait aux 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 seulement M / F, il serait facile d'utiliser un conditionnel, et de dire "Si: sex == 'F' alors utilisez cette formule, si: sex == 'M' puis modifiez la formule en dire {mean (: height [(: height << obtenir datatable) << obtenir des lignes où (: 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 conditionnels imbriqués deviendrait peu maniable.)
Y a-t-il un moyen simple d'y parvenir?
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 @MarkJSchwab ,
Oui, je peux voir à quel point l'envelopper dans des conditions conditionnelles n'est peut-être pas idéal dans de nombreux cas. Voici une modification de @brady_brady la solution 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 saisissons la valeur de: sex pour la ligne actuelle, nous la sauvegardons dans une variable, testVal. Ensuite, lorsque nous évaluons la fonction de centrage, nous pouvons tester l'utilisation de cette valeur dans la fonction get rows where ().
Voici le tableau avec une colonne contenant uniquement les lignes sélectionnées par cette fonction Get Rows Where ():

Comme vous pouvez le voir, toutes les lignes utilisent l'âge 14 comme sous-ensemble, mais quel sous-ensemble de sexe est déterminé par les valeurs de ligne actuelles de sexe. Doit être facilement adapté à différents niveaux de complexité.
@julien