Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Sto cercando un modo per prendere un sottoinsieme di una tabella di dati che utilizza solo righe che corrispondono a una condizione specificata e sottrarre la media di quelle righe da una colonna.
Ad esempio, utilizzando il set di dati Big Class, diciamo che voglio creare una nuova colonna che mostri "Differenza di altezza tra questo studente e la media di 14 anni dello stesso sesso".
Il modo in cui so come farlo è aggiungendo una seconda tabella, utilizzando Tabelle -> Riepilogo -> Statistiche: Media (altezza), Gruppo: sesso, Sottogruppo: età. Quindi posso Tabella -> Aggiorna: Grande classe per (sesso), Abbina colonne: sesso = sesso, e questo aggiungerà diverse colonne per Media (altezza, [età]). Quindi posso creare una nuova colonna "Altezza delta vs 14 anni dello stesso sesso" ovvero: altezza -: Media (altezza, 14).
La mia domanda: esiste un modo per fare a meno di creare una tabella aggiuntiva e la colonna aggiuntiva (ad esempio "Media (altezza, 14)")? Sembra che Col Mean (x, byVar) sia vicino a fornire questa funzionalità, ma priva della funzionalità per selezionare un gruppo diverso; ad esempio potrei usare: height - Col Mean (: height,: age,: sex) per trovare il delta tra lo studente X e lo studente medio del proprio sesso e altezza, ma non so se c'è un modo per specificare in Col Significa che desidero considerare solo le righe con età = 14, anziché utilizzare il valore dell'età associato a quella riga.
Faccio questo tipo di normalizzazione molto frequentemente, quindi qualsiasi cosa per renderla più veloce e più facile sarebbe enormemente apprezzata!
Tabella datiRi: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao, MarkJSchwab!
Certo, c'è un modo per fare ciò che desideri.JSL ti renderà libero!
Ho scritto un semplice script che utilizza principalmente la capacità di JSL di scrivere uno script per te.Provalo:
// 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 );
Ho creato una tabella di riepilogo separata e poi l'ho chiusa, ma non devi farlo in questo modo.
Ci sono, ovviamente, modi più sofisticati per scrivere uno script come questo, soprattutto perché tutte le clausole "where" sono hard-coded e potresti incorrere in problemi con questo script se la tua tabella dati è grande, ma, ancora, JSL sarà la tua strada verso la produttività.Ci sono molte ottime risorse per imparare JSL!
In bocca al lupo!
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao @MarkJSchwab ,
C'è un modo semplice per farlo usando Col Mean () che non è ovvio finché non lo vedi. Col Mean () accetta un argomento della colonna Frequenza:

Di solito, questo è per quando è necessario pesare utilizzando un'altra colonna. Ma, nel tuo esempio, cosa succederebbe se potessimo pesare i valori di Age == 14 come 1 e tutti gli altri valori come 0? Questo ci darebbe una media solo di quegli individui in cui Age == 14. Possiamo farlo direttamente nella formula:
Col Mean( :height, <<FREQ></FREQ>

Questo restituirà:

Ora, per la tua domanda specifica, centrandola rispetto a questa specifica media dall'altezza, possiamo racchiuderla nella formula nel solito modo:
:height - (Col Mean( :height, <<FREQ></FREQ>


Spero che questo aiuti!
@julian
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao @julian , grazie per il suggerimento. Purtroppo quando incollo quella formula esatta
Col Mean( :height, <<FREQ></FREQ>
nella mia classe grande, restituisce 62,55 (ovvero la media colonna complessiva senza selezionare l'età = 14) invece del valore corretto che stai vedendo di 64,166.
Posso persino scaricare il tuo allegato e i valori corretti vengono visualizzati nella colonna "Centrato rispetto alla media all'età == 14". Ma se creo una nuova colonna in quella tabella con la stessa identica formula, restituisce valori diversi (mostrando [altezza] - [altezza media complessiva], invece di mostrare correttamente [altezza] - [altezza media di 14 anni]).
Sto usando JMP Pro 14.3.0. Qualche idea su come posso far sì che il mio output corrisponda al tuo?
E un'altra domanda, sul tuo foglio se aggiungi un'ulteriore byVar di: sex (per la formula totale ": height - (Col Mean (: height,: sex, << Freq (: age == 14)))" lo fa sottrarre l'altezza media di un ragazzo di 14 anni dai ragazzi e l'altezza media di una ragazza di 14 anni dalle ragazze?
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao @MarkJSchwab ,
Sembra che << Freq sia stato aggiunto come argomento opzionale in JMP 15, quindi per le versioni precedenti di JMP sarà necessario fare qualcos'altro.
Ecco una soluzione dalla procedura guidata di jmp @brady_brady :
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 )] )

Vale la pena spendere un momento per decomprimere questa formula perché ci sono alcuni metodi che scommetto che troverai utili da usare in seguito.
(:height << get datatable) << get rows where( :age == 14 )
restituirà la matrice delle voci di riga in cui: age == 14. È importante sottolineare che puoi modificare la funzione get rows where () per abbinare qualsiasi ricerca desideri, inclusa la seconda domanda che credo tu abbia di includere un'altra variabile. Per esempio:
(:height << get datatable) << get rows where( :age == 14 & :sex == "F"

Ora che abbiamo una matrice di righe che corrispondono alla tua condizione, Brady usa questa matrice per indicare: altezza.
height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )]

Questo restituirà la matrice dei valori di: altezza per ciascuna di quelle righe, in questo caso, le altezze delle studentesse di 14 anni: [61, 62, 65, 63, 62]
Infine, la funzione Mean () è avvolta attorno a questa matrice, che restituisce la media necessaria per calcolare la variabile centrata:
mean(:height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )])

Questa soluzione è più flessibile, tollera i dati mancanti e funziona per le versioni precedenti di jmp, quindi credo sia una soluzione migliore. Grazie, @brady_brady !
@julian
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao @julian Grazie ancora per l'aiuto!
Un'ultima ruga: idealmente vorrei che l'età media delle ragazze di 14 anni fosse sottratta dalle ragazze e che l'età media dei ragazzi di 14 anni fosse sottratta dai ragazzi. (Nel tuo esempio, sottrai l'età di 14 anni sia dai maschi che dalle femmine.)
(Mi rendo conto che in questo caso specifico con solo M / F sarebbe facile usare un condizionale e dire "If: sex == 'F' allora usa questa formula, se: sex == 'M' allora modifica la formula in dì {mean (: height [(: height << get datatable) << get rows where (: age == 14 &: sex == "M")])} "ma nei miei casi d'uso più generali potrei avere un un gran numero di gruppi e condizionali annidati diventerebbe ingombrante.)
Qualche modo semplice per ottenere questo risultato?
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Hai solo bisogno di espandere la formula per gestire sia il maschio che la femmina
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" )] )
)
Ri: Formula per sottrarre la media di un sottoinsieme da una colonna di dati?Ciao @MarkJSchwab ,
Sì, posso vedere come avvolgere questo in condizionali potrebbe non essere l'ideale per molti casi. Ecco una modifica a @brady_brady La soluzione che dovrebbe funzionare (tabella allegata):

testVal = :sex;
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 & :sex == testVal )] );
In questo caso, prendiamo il valore di: sex per la riga corrente, salvandola in una variabile, testVal. Quindi, quando valutiamo la funzione di centratura, possiamo testare l'uso di quel valore nella funzione get rows where ().
Ecco la tabella con una colonna delle sole righe selezionate da questa funzione Get Rows Where ():

Come puoi vedere, tutte le righe usano l'età 14 come sottoinsieme, ma quale sottoinsieme di sesso è determinato dai valori correnti delle righe di sesso. Dovrebbe essere facilmente adattato a diversi livelli di complessità.
@julian