被験者間1要因分散分析
非反復要因/非繰り返し要因
被験者間1要因分散分析(岡本安晴「データ分析のための統計学入門」おうふう)のVisual C++/win32プログラムを作成した。なお、Win32コンソールアプリケーションの新規作成については<Win32コンソールアプリケーションの新規作成>で、C++の標準入出力(コンソール入出力)については<標準入出力cinとcout>で、C++におけるテキストファイル入出力については<テキストファイル入出力>で説明している。
プログラムの実行例を図1に示す。
図1
入力ファイルはプログラム・ソースコード・ファイル*.cppと同じフォルダに用意する。
入力データファイル設定のソースコードは以下のようになっている。
cout << "入力データファイル = " ;
string ifnm;
cin >> ifnm;
ifstream fin( ifnm );
if ( ! fin){ // 入力ファイルの設定が失敗するとfinはfalseを返す。
cout << "入力ファイルエラー" << endl;
cout << "何か文字を入力して終了。" << endl;
string s;
cin >> s;
return 9;
}
入出力ストリーム・オブジェクトの変数finを条件式に用いると、ストリームに何かエラーがあるとfalseが返される。
入力ファイルは図2の形式で用意する。
図2
第1行に水準数aと水準内のデータ数nを書く。次の行から、第1列に第1水準のデータ、・・・、第a列に第a水準のデータを書く。必要なデータが書かれた後は、読み込みの対象とはならないので、コメントを自由に書くことができる。
エディタでデータを新しく用意したときは、保存してからプログラムで読み込む。エディタの画面に打ち込んだだけでは、その内容はファイルに反映されない。
図2の形式のデータファイルに対する読み込みは、次のコードによって行っている。
int a, n;
fin >> a >> n;
double ** y; // データ設定用配列 y[データ番号][水準]
y = new double*[n];
for (int i = 0; i < n; i++)
y[i] = new double[a];
double * my;
my = new double[a];
for(int i = 0; i < n; i++){
for (int j = 0; j < a; j++)
fin >> y[i][j];
}
計算を終えて結果の書き出しが終了すると「何か文字を入力して終了」と表示されるので、適当な文字キーを押してEnterキーを押すとプログラムの終了となる。この部分は以下のコードによって処理されている。
fout.close();
cout << endl << "計算終了" << endl;
cout << "何か文字を入力して終了" << endl;
string ckstr;
cin >>ckstr;
return 0;
出力ファイルもファイル名を図1のように設定すると、プログラムソースコードファイル*.cppと同じフォルダ内に作成される。図2のデータでプログラムを実行したときの出力ファイルをVisualC++のエディタで開くと図3のようになっている。
図3
要因Aの水準数が2ケタになっても右側で揃うように、次のようなコードで書き出している。
for (int j = 0; j < a; j++){
ostringstream sout;
sout << "A" << j+1;
fout << setw(15) << sout.str();
}
ストリームostringstream型は文字列への書き出し、すなわちメモリ上への書き出しを行う出力用の文字列ストリームであり、書き出された結果はstr( )関数によって文字列として取り出せる。
fout << setw(15)
におけるsetw(15)は、書式(フォーマット)を指定するマニピュレータと呼ばれているものの1つで、setw( k )を出力すると、setw(k)に続く出力はk文字分の長さになるように空白文字を補って出力される。
平均値は、小数点以下2桁の出力に揃えられているが、これは以下のコードによる。
fout << "平均値" << endl;
fout << setprecision(2) << fixed;
for (int j = 0; j < a; j++)
fout << setw(15) << my[j];
fout << endl;
「setprecision( s ) << fixed」と出力すると、それ以降の実数値の出力は小数点以下s桁で書き出される。この設定を初期状態に戻すためには
fout << resetiosflags(ios_base::floatfield);
を実行する。
分散分析表は、上で説明したマニピュレータを用いて図3に示されているように右側で揃えた形式で書き出されている。
プログラムソースコード全体は以下の通りである。
==============================================
#include "stdafx.h" // Visual C++が勝手に用意するもの。削除するとエラーになる。
#include <iostream> // cin, coutの使用のため
#include <fstream> // ifstream, ifstreamの使用のため
#include <iomanip> // setwなどの使用のため
#include <string> // string型の使用のため
#include <sstream> // 文字列ストリーム使用のため
using namespace std; // cin, coutなどが属する名前空間
double sqr( double v ){
return v * v;
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "入力データファイル = " ;
string ifnm;
cin >> ifnm;
ifstream fin( ifnm );
if ( ! fin){ // 入力ファイルの設定が失敗するとfinはfalseを返す。
cout << "入力ファイルエラー" << endl;
cout << "何か文字を入力して終了。" << endl;
string s;
cin >> s;
return 9;
}
int a, n;
fin >> a >> n;
double ** y; // データ設定用配列 y[データ番号][水準]
y = new double*[n];
for (int i = 0; i < n; i++)
y[i] = new double[a];
double * my;
my = new double[a];
for(int i = 0; i < n; i++){
for (int j = 0; j < a; j++)
fin >> y[i][j];
}
fin.close();
cout << "出力ファイル名 = ";
string ofnm;
cin >> ofnm;
ofstream fout( ofnm );
fout << "データファイル..." << ofnm << endl << endl;
fout << "データ = " << endl;
for (int j = 0; j < a; j++){
ostringstream sout;
sout << "A" << j+1;
fout << setw(15) << sout.str();
}
fout << endl << endl;
for (int i = 0; i < n; i++){
for (int j = 0; j < a; j++)
fout << setw(15) << y[i][j];
fout << endl;
}
double g_my = 0.0;
for (int j = 0; j < a; j++){
my[j] = 0.0;
for (int i = 0; i < n; i++) my[j] += y[i][j];
g_my += my[j];
my[j] /= double(n); // 水準jの平均
}
g_my /= double(a * n); // 全体の平均
fout << "平均値" << endl;
fout << setprecision(2) << fixed;
for (int j = 0; j < a; j++)
fout << setw(15) << my[j];
fout << endl;
double ss_a = 0.0;
double ss_sa = 0.0;
for (int j = 0; j < a; j++){
ss_a += n * sqr( my[j] - g_my ); // 級間平方和
for (int i = 0; i < n; i++)
ss_sa += sqr( y[i][j] - my[j] ); // 級内平方和
}
double ss_total = ss_a + ss_sa; // データ全体の変動量
double ms_a = ss_a / (a - 1.0); // 級間平均平方和
double ms_sa = ss_sa / (a * (n - 1)); // 級内平均平方和
double f = ms_a / ms_sa; // F値
fout << endl << endl;
fout << setw(21) << "平方和" << setw(15) << "自由度" << setw(15) << "平均平方和" << setw(15) << "F" << endl;
fout << setprecision(3) << fixed;
fout << "級間 " << setw(15) << ss_a << setw(15) << a-1 << setw(15) << ms_a << setw(15) << f << endl;
fout << "級内 " << setw(15) << ss_sa << setw(15) << a*(n-1) << setw(15) << ms_sa << endl;
fout << "計 " << setw(15) << ss_total << setw(15) << a*n-1 << endl;
fout.close();
cout << endl << "計算終了" << endl;
cout << "何か文字を入力して終了" << endl;
string ckstr;
cin >>ckstr;
return 0;
}
==============================================
プログラムソースコードファイルなどをまとめたものは圧縮ファイルanovabtwn1fctr.zipとして用意した。圧縮ファイル名anovabtwn1fctr.zipをクリックしてダウンロードすることが出来る。ダウンロードした圧縮ファイルanovabtwn1fctr.zipはマウスの右ボタンクリックで表示されるメニュから「展開」あるいは「解凍」を選ぶと解凍できる。解凍したファイルはVisual C++2010で開くことができる。
Visual C++プログラミングの入門書として<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>を上梓した。