從數據列中減去子集的平均值的公式?我正在尋找一種方法來獲取僅使用符合指定條件的行的數據表的子集,並從列中減去這些行的均值。
例如,使用Big Class數據集,說我想創建一個新列,顯示“該學生與同性別的平均14歲學生之間的身高差異。”
我知道如何執行此操作的方法是添加第二張表,方法是使用表->摘要->統計信息:均值(高度),組:性別,子組:年齡。 然後我可以在Table-> Update:Big Class By(性別)中,匹配列:sex = sex,這將為Mean(height,[age])添加幾列。 然後,我可以創建一個新列“ Delta height vs 14yo of same sex”,即:height-:Mean(height,14)。
我的問題:沒有創建額外的表和額外的列(例如“ Mean(height,14)”),有什麼辦法嗎? 似乎Col Mean(x,byVar)即將提供此功能,但缺少選擇其他組的功能;例如,我可以使用:height-Col Mean(:height,:age,:sex)查找學生X與他們自己性別和身高的普通學生之間的差異,但我不知道是否有一種方法可以指定在Col中表示我只想考慮age = 14的行,而不要使用與該行關聯的age值。
我經常進行這種類型的標準化,因此,使它變得更快,更容易的任何事情將不勝感激!
數據表回复:從數據列中減去子集的平均值的公式?嗨,MarkJSchwab!
當然,有一種方法可以做您想要的。JSL將讓您自由!
我編寫了一個簡單的腳本,該腳本主要使用JSL的功能為您編寫腳本。試試吧:
// 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 );
我製作了一個單獨的摘要表,然後將其關閉,但是您不必那樣做。
當然,有類似這樣的腳本可以編寫出更複雜的方法,特別是因為所有“ where”子句都是硬編碼的,並且如果您的數據表很大,則可能會遇到此腳本問題,但是,即使如此,JSL將是您提高生產力的途徑。有很多學習JSL的資源!
祝你好運!
回复:從數據列中減去子集的平均值的公式?你好@MarkJSchwab ,
有一種使用Col Mean()進行操作的簡單方法,除非您看到它,否則還不明顯。 Col Mean()採用頻率列參數:

通常,這是當您需要使用另一列進行加權時。 但是,在您的示例中,如果我們可以將Age == 14的值加權為1,將所有其他值加權為0,該怎麼辦? 這將使我們僅獲得年齡== 14的那些人的平均值。 我們可以直接在公式中執行此操作:
Col Mean( :height, <<FREQ></FREQ>

這將返回:

現在,對於您的特定問題,以從高度開始的特定均值為中心,我們可以按通常方式將其包裝到公式中:
:height - (Col Mean( :height, <<FREQ></FREQ>


我希望這有幫助!
@朱利安
回复:從數據列中減去子集的平均值的公式?你好@朱利安,感謝您的建議。 不幸的是,當我粘貼該確切公式時
Col Mean( :height, <<FREQ></FREQ>
進入我的大類,它將返回62.55(即不選擇age = 14的總體Col Mean),而不是您看到的正確值64.166。
我什至可以下載您的附件,並且適當的值會顯示在“相對於年齡平均值== 14居中”列中。 但是,如果我在該表中使用完全相同的公式創建新列,則會返回不同的值(顯示[height]-[overall avg height],而不是正確顯示[height]-[14yos的平均高度])。
我正在使用JMP Pro 14.3.0。 關於如何獲得與您匹配的輸出的任何想法?
還有一個問題,在表上,如果您添加一個額外的byVar:sex(對於總公式“:height-(Col Mean(:height,:sex,<< Freq(:age == 14)))”)從男孩中減去平均14yo男孩身高,然後從女孩中減去14yo女孩平均身高?
回复:從數據列中減去子集的平均值的公式?你好@MarkJSchwab ,
確實出現了<<在JMP 15中添加了頻率作為可選參數的情況,因此對於JMP的早期版本,您將需要執行其他操作。
這是jmp嚮導的解決方案@brady_brady :
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 )] )

值得花一點時間來解開此公式,因為我敢打賭有些方法您以後會發現有價值。
(:height << get datatable) << get rows where( :age == 14 )
將返回行條目的矩陣,其中:age == 14。 重要的是,您可以修改get rows where()函數以匹配所需的任何查找,包括第二個詢問(我相信您要包含另一個變量)。 例如:
(:height << get datatable) << get rows where( :age == 14 & :sex == "F"

現在,我們有了一個符合您條件的行矩陣,布雷迪使用此矩陣下標:height。
height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )]

這將返回每行的:height值的矩陣,在這種情況下,將返回14歲女學生的身高:[61,62,65,63,62]
最後,Mean()函數圍繞此矩陣包裝,該矩陣返回您需要計算中心變量的均值:
mean(:height[(:height << get datatable) << get rows where( :age == 14 & :sex == "F" )])

該解決方案更加靈活,可以容忍丟失的數據,並且適用於jmp的早期版本,因此,我認為這是一個更好的解決方案。 謝謝, @brady_brady !
@朱利安
回复:從數據列中減去子集的平均值的公式?你好@朱利安再次感謝您的幫助!
最後的皺紋:理想情況下,我希望女孩平均減去14歲的女孩年齡,男孩平均減去14歲的男孩年齡。 (在您的示例中,您正在從男孩和女孩中減去14歲的女孩。)
(我意識到,在這種僅使用M / F的特定情況下,使用條件運算會很容易,然後說“如果:sex =='F',則使用此公式,如果:sex =='M',則將公式修改為說{mean(:height [(:height <<獲取數據表)<<獲取行where(:age == 14&:sex ==“ M”)])}“”,但在我更一般的用例中,我可能有一個大量的組和嵌套的條件將變得笨拙。)
有什麼簡單的方法可以實現這一目標嗎?
回复:從數據列中減去子集的平均值的公式?您只需要擴展公式即可處理男性和女性
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" )] )
)
回复:從數據列中減去子集的平均值的公式?你好@MarkJSchwab ,
是的,我可以看到在很多情況下將其包裝在條件語句中可能並不理想。 這是對@brady_brady的解決方案(附表):

testVal = :sex;
:height - Mean( :height[(:height << get datatable) << get rows where( :age == 14 & :sex == testVal )] );
在這種情況下,我們獲取當前行:sex的值,並將其保存到變量testVal中。 然後,當我們評估居中功能時,我們可以測試在get row where()函數中使用該值。
這是一個表,其中僅包含此Get Rows Where()函數選擇的行的列:

如您所見,所有行都使用14歲作為子集,但是哪個性別子集由當前行的sex值確定。 應易於適應不同級別的複雜性。
@朱利安