被験者間2要因分散分析
被験者間2要因分散分析のためのVisual C++プログラムを作成した。この分散分析については<岡本安晴「データ分析のための統計学入門」2009、おうふう;第4章:分散分析>などを参照されたい。プログラムは、ウェブサイト<テキストファイル入出力>で説明したプログラムに下記のようにコードを書き加えて作成した。
===============================================
//
// pos
番目の文字列の取り出し
//
String
^ SeekStr( String ^ str, int pos ){
String
^ vstr = "";
array<wchar_t>
^ separator = { ' ', '\t', ',',' ','/' };
array<String ^> ^ ary_str;
ary_str
= str->Split( separator );
int L = ary_str->Length;
int ckp = -1;
int tmpPos = 0;
do {
if (ary_str[tmpPos]->Length > 0) ckp++;
tmpPos++;
}
while ((ckp != pos) && (tmpPos < L)
);
if (ckp == pos) vstr = ary_str[tmpPos-1];
return vstr;
}
double sqr( double v
){
return v * v;
}
private: System::Void
button1_Click(System::Object^
sender, System::EventArgs^
e) {
//
// 入出力ファイルの名の設定
//
openFileDialog1->Title = "入力データファイル名";
if
(openFileDialog1->ShowDialog() ==
System::Windows::Forms::DialogResult::Cancel) return;
saveFileDialog1->Title = "出力ファイル名";
if
(saveFileDialog1->ShowDialog() ==
System::Windows::Forms::DialogResult::Cancel) return;
using namespace System::IO;
//
// 入力ストリームと出力ストリームの設定
//
StreamReader ^ fin = gcnew StreamReader( openFileDialog1->FileName,
System::Text::Encoding::GetEncoding("shift-jis")
);
StreamWriter ^ fout = gcnew StreamWriter( saveFileDialog1->FileName, false, System::Text::Encoding::GetEncoding("shift-jis") );
fout->WriteLine("Data file..." +
openFileDialog1->FileName);
fout->WriteLine();
String ^s;
while(true){
s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
s = fin->ReadLine();
int a = int::Parse(SeekStr(s, 0));
int b = int::Parse(SeekStr(s, 1));
int n = int::Parse(SeekStr(s, 2));
double
*** y;
y = new double**[n];
for (int i = 0; i < n; i++){
y[i]
= new double*[a];
for (int j = 0; j
< a; j++)
y[i][j]
= new double[b];
}
for (int j = 0; j < a; j++){
while(true){
s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
for (int i = 0; i < n; i++){
s = fin->ReadLine();
for (int k = 0; k < b; k++)
y[i][j][k] = double::Parse(SeekStr(s,
k));
}
}
//
// 平方和の計算
//
double v = 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
double rn = n;
double ss_c = sqr(v) / (rn * a * b);
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++)
v
+= sqr(y[i][j][k]);
double ss_total = v - ss_c;
double ss_a = 0.0;
for (int j = 0; j
< a; j++){
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
ss_a
+= sqr(v);
}
ss_a
= (ss_a / (rn * b)) - ss_c;
double ss_b = 0.0;
for (int k = 0; k
< b; k++){
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
v
+= y[i][j][k];
ss_b
+= sqr(v);
}
ss_b
= (ss_b / (rn * a)) - ss_c;
double ss_ab = 0.0;
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++){
v
= 0.0;
for (int i = 0; i
< n; i++)
v
+= y[i][j][k];
ss_ab
+= sqr(v);
}
ss_ab
= (ss_ab / rn) - ss_c - ss_a - ss_b;
double ss_err = ss_total - ss_a - ss_b - ss_ab;
double * sum;
sum
= new double[b];
fout->WriteLine();
fout->WriteLine();
for (int j = 0; j
< a; j++){
fout->WriteLine();
fout->WriteLine("<水準A-" + (j+1).ToString() +">");
for (int k = 0; k
< b; k++){
fout->Write(("<水準B-" + (k+1).ToString() + ">")->PadLeft(15));
sum[k]
= 0.0;
}
fout->WriteLine();
for (int i = 0; i
< n; i++){
for (int k = 0; k
< b; k++){
fout->Write((y[i][j][k].ToString())->PadLeft(15));
sum[k]
+= y[i][j][k];
}
fout->WriteLine();
}
fout->WriteLine("平均");
for (int k = 0; k
< b; k++)
fout->Write(
((sum[k]/n).ToString("F2"))->PadLeft(15));
fout->WriteLine();
}
fout->WriteLine();
fout->WriteLine();
fout->WriteLine(String("SV").PadLeft(10) + String("SS").PadLeft(15) + String("df").PadLeft(10) + String("MS").PadLeft(15) + String("F").PadLeft(15));
fout->WriteLine(String("A").PadLeft(10) + ss_a.ToString("F3")->PadLeft(15) +
(a-1).ToString()->PadLeft(10) + (ss_a/(a-1)).ToString("F3")->PadLeft(15) +
((ss_a/(a-1))
/ (ss_err/(a * b * (n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("B").PadLeft(10) + ss_b.ToString("F3")->PadLeft(15) +
(b-1).ToString()->PadLeft(10) + (ss_b/(b-1)).ToString("F3")->PadLeft(15) +
((ss_b/(b-1))
/ (ss_err/(a * b * (n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("AB").PadLeft(10) + ss_ab.ToString("F3")->PadLeft(15) +
((a-1)*(b-1)).ToString()->PadLeft(10) + (ss_ab/((a-1.0)*(b-1.0))).ToString("F3")->PadLeft(15) +
((ss_ab/((a-1.0)*(b-1.0)))
/ (ss_err/(a * b * (n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("S/AB").PadLeft(10) + ss_err.ToString("F3")->PadLeft(15) + (a*b*(n-1)).ToString()->PadLeft(10)
+ (ss_err / (a * b * (n - 1.0))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("Total").PadLeft(10) +
ss_total.ToString("F3")->PadLeft(15)
+ (a * b * n - 1).ToString()->PadLeft(10));
fout->Close();
MessageBox::Show(saveFileDialog1->FileName
+ " was saved.");
Close();
}
===============================================
このプログラムを実行すると図1のウィンドウが表示される。
図1
「button1」ボタンのクリックで入力データ名設定用ダイアログウィンドウが図2のように表示される。
図2
入力データファイル名を指定して「開く」ボタンをクリックすると、計算結果出力用のファイル名設定を求めるダイアログウィンドウが表示される(図3)。
図3
出力はテキストファイルとして書き出されるので、ファイル名の拡張子は「.txt」としておく。出力ファイル名の設定後、「保存」ボタンをクリックすると計算がはじまり、計算終了後図4のメッセージウィンドウが表示される。
図4
メッセージウィンドウの「OK」ボタンのクリックでプログラムが終了する。
入力データは、図5に示すようにスラッシュ/で始まる行の次の行に、まず2つの要因の水準数とセル内データ数を書く。
図5
次の行から、第1要因(Aで表わしておく)の各水準ごとに、スラッシュで始まる行に続けて第2要因(Bで表わしておく)の水準が列に対応するようにデータを書く。図5の場合、要因Aの第1水準A1と要因Bの第1水準B1の組み合わせに対するデータが、24, 33, 37, 29, 42 であり、水準A3と水準B3の組み合わせに対するデータは 42, 52, 53, 49, 64 である。
図5のファイルを入力データとしたときの出力ファイルは次のようになっている。
============ 出力ファイル例:ここから ====================
Data
file...F:\yasuharu\www\LaCoocan\introprg\ANOVA2btwn\anova2btwn\anova2btwn\DataANOVA2btwn.txt
<水準A-1>
<水準B-1> <水準B-2> <水準B-3>
24
44
38
33
36
29
37
25
28
29
27
47
42 43
48
平均
33.00
35.00
38.00
<水準A-2>
<水準B-1> <水準B-2> <水準B-3>
30
35
26
21
40
27
39
27 36
26
31
46
34
22
45
平均
30.00
31.00
36.00
<水準A-3>
<水準B-1> <水準B-2> <水準B-3>
21
41
42
18
39
52
10
50
53
31
36
49
20
34
64
平均
20.00
40.00
52.00
SV
SS df
MS
F
A
190.000
2
95.000
1.520
B
1543.333
2
771.667
12.347
AB
1236.667
4
309.167
4.947
S/AB 2250.000
36
62.500
Total
5220.000 44
============ 出力ファイル例:ここまで========================
プログラム・ファイルは圧縮ファイルanova2btwn.zipとしてまとめた。ファイル名anova2btwn.zipをクリックしてダウンロードしたものをマウスの右ボタンクリックで表示されるメニュ「解凍」あるいは「展開」などを選ぶと解凍できる。解凍したものはVisual C++などで開いてビルド実行することができる。実行形式ファイルanova2btwn.exeも用意したので、ファイル名anova2btwn.exeをクリックしてダウンロード実行することができる。実行形式ファイルは.NET Framework3.5対応である。
なお、F値に対応する確率を求めるVisual C++プログラムはウェブサイト<エフ分布>に用意した。