Function Tukey(RNGdt As Range, TST1 As Integer, TST2 As Integer, Optional RCtyp As Integer)
Dim Nsj As Integer, SJ() As Range, Isj As Integer, Ndt() As Integer, SM() As Double, SM2() As Double, AVR() As Double
Dim Idt As Integer, DT As Double, DT2 As Double, Sdt2() As Double, SMt As Double
Dim Nt As Integer, AVRt As Double, St As Double, Sb As Double, Sw As Double, DIFsj() As Double
Dim DFt As Integer, DFb As Integer, DFw As Integer, Vw As Double, F5 As Double, F1 As Double, Qtk As Double
If RCtyp = 2 Then
Nsj = RNGdt.Rows.Count
Else
Nsj = RNGdt.Columns.Count
End If
ReDim SJ(Nsj), Ndt(Nsj), SM(Nsj), SM2(Nsj), AVR(Nsj), Sdt2(Nsj), DIFsj(Nsj)
If RCtyp = 2 Then
For Isj = 1 To Nsj
Set SJ(Isj) = RNGdt.Rows(Isj)
Next Isj
Else
For Isj = 1 To Nsj
Set SJ(Isj) = RNGdt.Columns(Isj)
Next Isj
End If
For Isj = 1 To Nsj
Ndt(Isj) = WorksheetFunction.Count(SJ(Isj)) '水準データ数
SM(Isj) = WorksheetFunction.Sum(SJ(Isj)) '水準合計値
SM2(Isj) = SM(Isj) * SM(Isj) '水準合計の平方値
AVR(Isj) = WorksheetFunction.Average(SJ(Isj)) '水準平均値
For Idt = 1 To Ndt(Isj)
DT = SJ(Isj).Cells(Idt).Value '個別データ取得
DT2 = DT * DT '個別データの平方値
Sdt2(Isj) = Sdt2(Isj) + DT2 '水準毎の平方値の和
Next Idt
Next Isj
SMt = WorksheetFunction.Sum(SM) 'データ総和
Nt = WorksheetFunction.Sum(Ndt) '総データ数
AVRt = SMt / Nt '総平均値
St = WorksheetFunction.Sum(Sdt2) - SMt * SMt / Nt '総平方和
For Isj = 1 To Nsj
DIFsj(Isj) = (AVR(Isj) - AVRt) * (AVR(Isj) - AVRt) * Ndt(Isj)
Next Isj
Sb = WorksheetFunction.Sum(DIFsj) '水準間平方和
Sw = St - Sb '水準内平方和
DFt = Nt - 1 '全体の自由度
DFb = Nsj - 1 '水準間の自由度
DFw = Nt - Nsj '水準内の自由度
Vw = Sw / DFw '水準内の平均平方
F5 = WorksheetFunction.FInv(0.05, DFb, DFw) / Sqr(2) 'p=0.05におけるF境界値
F1 = WorksheetFunction.FInv(0.01, DFb, DFw) / Sqr(2) 'p=0.01におけるF境界値
Qtk = Abs(AVR(TST1) - AVR(TST2)) / Sqr(Vw * (1 / Ndt(TST1) + 1 / Ndt(TST2))) '検定統計量
If Qtk <= F5 Then
Tukey = "-"
ElseIf Qtk <= F1 Then
Tukey = "*"
Else
Tukey = "**"
End If
End Function
No.07553 Re: Tukey-Kramer法のExcelVBAについて 【青木繁伸】 2008/09/02(Tue) 14:38
結果で -,*,** だけを返すのはもったいない
統計量,P値を返す方がよいでしょう
テストデータと結果を付けると良いと思います
今回のプログラムの結果については検証していません
No.07555 Re: Tukey-Kramer法のExcelVBAについて 【むう】 2008/09/02(Tue) 15:38
早速のご意見ありがとうございます。
テストデータと結果を,とのことなので以下に示します。
《テストデータ》
水準1 水準2 水準3 水準4 水準5
14 17 18 20 19
15 16 19 21 20
14 17 20 19 19
16 16 19 20 17
15 15 17 19 17
17 18 17 22 17
17 19 20 18
15
《VBA中の各変数の値》
要因 偏差平方和 自由度 不偏分散 F値
全体変動 137.5428571 34 2.689627574(p<0.05)
因子間変動 90.90595238 4 4.017876837(p<0.01)
誤差変動 46.63690476 30 1.554563492
《統計値と判定》
qTK 判定
1vs2 1.854090495 −
1vs3 4.187542976 **
1vs4 7.073684570 **
1vs5 4.072727480 **
2vs3 2.537026384 *
2vs4 5.451579515 **
2vs5 2.352204359 *
3vs4 2.608633329 *
3vs5 0.274592982 −
4vs5 3.000957090 **
No.07556 Re: Tukey-Kramer法のExcelVBAについて 【にゃんちゅう】 2008/09/02(Tue) 17:39
違ってますね。
分散分析の表が違っているのはなぜ?
LSD と Tukeyの多重比較の区別はつきますか?
WorksheetFunction.FInvではだめですよね。
No.07558 Re: Tukey-Kramer法のExcelVBAについて 【青木繁伸】 2008/09/02(Tue) 21:00
> これで正しい検定ができているのかイマイチ自信が持てずに困っています。
プログラムを作って,正しく計算できているかどうかチェックするのは,簡単です。
答えの分かっているデータを与えて,正しい答えが出るかどうかを確かめればよいだけです。
後, チェックの要点は,境界領域で正しい答えが出るかどうかやってみる。例えば,群の数が3以上となっているときに,二群を指定したらどうなるかとか,10群 まで出来るはずだけど11群を指定したらどうなるかとか。オプションを指定したときに,正しくその指定を反映して計算してくれるか?とかね。
正の値しか受け付けないはずのデータとして負の値や0を与えたらどうなるかとか,整数値しか駄目なものに小数付きのデータを与えたらどうなるかとか。要するに,プログラムが予期しないデータを受け取ったときにも正しく処理できるようにすること。
アプリケーションの半分以上は,データやパラメータが適正かどうかの判定と処理に関するものであると思いますね(つまらない処理・確認ですけど,人間はいつも理不尽な処理を命令するものだと思うべし)。
この辺りをちゃんとやらないと,某証券市場システムのように,注文が100以上になると処理できないとか,ある会社を指定したときに処理できないとか,色々不都合が生じるのです。
理想的にというか当たり前というか,あらゆる条件の組み合わせに対応するテストデータを用意し(当然,その時の正しい結果が分かっている必要がある),正しい結果が出ることを確かめるのです。そうしないと,そのプログラムの妥当性は保証されません。
そういうことをふまえると,あるプログラムが正しいかどうかは,そのプログラムの作者が確かめるしかない(他の人に検証を委任するのは無責任)。
他の人は,もしあれば,(特定の条件下における)プログラムの欠陥を指摘するのみ。
No.07560 Re: Tukey-Kramer法のExcelVBAについて 【kai】 2008/09/03(Wed) 08:50
にゃんちゅうさんも指摘していますが,全体変動はあっているのに,因子間変動と誤差変動は間違っています.どこかで計算間違いをしているのでは?(VBAはわからないので確認をお願いします)
No.07567 Re: Tukey-Kramer法のExcelVBAについて 【知ったかぶり】 2008/09/03(Wed) 16:27
にゃんちゅうさん御指摘のように,Finvではtukeyの検定統計量は求められないでしょう.
過去ログにこんなのが.
http://aoki2.si.gunma-u.ac.jp/lecture/mb-arc/arc018/346.html
VBAでやってやれないことはないでしょうが,Rを使えばシアワセになれると思います.
● 「統計学関連なんでもあり」の過去ログ--- 042 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る