上へ

被験者間1要因分散分析

 

被験者間1要因(非繰り返し要因、非反復要因)分散分析のための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 n = int::Parse(SeekStr(s, 1));

 

                                 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++){

                                         s = fin->ReadLine();

                                         for (int j = 0; j < a; j++)

                                                 y[i][j] = double::Parse(SeekStr(s, j));

                                 }

 

                                //         データの書き出し

                                fout->WriteLine("データ= ");

                                for (int j = 0; j < a; j++)

                                        fout->Write(("A" + (j+1).ToString())->PadLeft(15));

                                fout->WriteLine();

                                for(int i = 0; i < n; i++){

                                        for (int j = 0; j < a; j++)

                                                fout->Write( (y[i][j].ToString("F2"))->PadLeft(15) );

                                        fout->WriteLine();

                                }

 

                                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->WriteLine();

                                fout->WriteLine("平均値");

                                for (int j = 0; j < a; j++) fout->Write( my[j].ToString()->PadLeft(15) );

                                fout->WriteLine();

 

                                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->WriteLine();

                                fout->WriteLine();

                                fout->WriteLine(String(" ").PadLeft(6+9) + "平方和" + String(" ").PadLeft(9) + "自由度" +

                                                                String(" ").PadLeft(5) + "平均平方和" + String("F").PadLeft(15) );

                                fout->WriteLine("級間 " + ss_a.ToString("F2")->PadLeft(15) + (a-1).ToString()->PadLeft(15) +

                                                                ms_a.ToString("F3")->PadLeft(15) + f.ToString("F3")->PadLeft(15) );

                                fout->WriteLine("級内 " + ss_sa.ToString("F2")->PadLeft(15) + (a*(n-1)).ToString()->PadLeft(15) +

                                                                ms_sa.ToString("F3")->PadLeft(15) );

                                fout->WriteLine("計  " + ss_total.ToString("F2")->PadLeft(15) + (a*n-1).ToString()->PadLeft(15) );

 

                                 fout->Close();

                                 MessageBox::Show(saveFileDialog1->FileName + " was saved.");

                                 Close();

                         }

===============================================

このプログラムを実行すると図1のウィンドウが表示される。

図1

 

button1」ボタンのクリックで入力データ名設定用ダイアログウィンドウが図2のように表示される。

図2

 

入力データファイル名を指定して「開く」ボタンをクリックすると、計算結果出力用のファイル名設定を求めるダイアログウィンドウが表示される(図3)。

図3

 

出力はテキストファイルとして書き出されるので、ファイル名の拡張子は「.txt」としておく。出力ファイル名の設定後、「保存」ボタンをクリックすると計算がはじまり、計算終了後図4のメッセージウィンドウが表示される。

図4

 

メッセージウィンドウの「OK」ボタンのクリックでプログラムが終了する。

入力データは、図5に示すようにスラッシュ/で始まる行の次の行に、まず水準数と水準内のデータ数を書く。

図5

 

次の行から、各行に各水準のデータを並べて書く。被験者間要因なので水準間のデータに対応はない。適当に1行に各水準からのデータを1つずつ取り出して並べる。図5の場合、1列目のデータ、83, 84, ・・・, 77が第1水準のデータ、2列目65, 80, ・・・, 66が第2水準のデータ、3列目77, 72, ・・・, 63が第3水準のデータである。

図5のファイルを入力データとしたときの出力ファイルは次のようになっている。

============ 出力ファイル例:ここから ====================

Data file...F:\yasuharu\www\LaCoocan\introprg\ANOVA1btwn\anova1btwn\anova1btwn\DataANOVA1btwn.txt

 

データ=

             A1             A2             A3

          83.00          65.00          77.00

          84.00          80.00          72.00

          74.00          81.00          70.00

          58.00          81.00          75.00

          73.00          80.00          65.00

          74.00          72.00          53.00

          66.00          56.00          67.00

          85.00          64.00          75.00

          61.00          70.00          60.00

          77.00          66.00          63.00

 

平均値

           73.5           71.5           67.7

 

 

               平方和        自由度    平均平方和             F

級間         173.60              2         86.800          1.162

級内        2017.10             27         74.707

計         2190.70             29

============ 出力ファイル例:ここまで========================

 

プログラム・ファイルは圧縮ファイルanova1btwn.zipとしてまとめた。ファイル名anova1btwn.zipをクリックしてダウンロードしたものをマウスの右ボタンクリックで表示されるメニュ「解凍」あるいは「展開」などを選ぶと解凍できる。解凍したものはVisual C++などで開いてビルド実行することができる。実行形式ファイルanova1btwn.exeも用意したので、ファイル名anova1btwn.exeをクリックしてダウンロード実行することができる。実行形式ファイルは.NET Framework3.5対応である。

なお、F値に対応する確率を求めるVisual C++プログラムはウェブサイト<エフ分布>に用意した。

 

上へ