Chapter 10

【フランカー課題】参加者情報の取得

snishiyama
snishiyama
2021.09.24に更新

本章の目的

心理学の論文では参加者の年齢や性別を報告します。本章では実験プログラム上で参加者情報を取得する方法について紹介します。本章の内容をこれまでのプログラムに組み込んだらフランカー課題は完成です。

参加者情報の取得

さっそく参加者情報を取得していきましょう。今回のチュートリアル課題で収集する情報は,参加者 ID,年齢,性別の 3 つとします。アンケート用のプラグインがあるのでそれを利用します。参加者 ID と年齢はjspsych-survey-text,性別はjspsych-survey-multi-choiceというプラグインを使って収集していきます。jspsych-survey-textは入力用のテキストボックスを表示し,jspsych-survey-multi-choiceは指定した選択肢を表示します。まずは以下のコードを実行してみてください。

get_participant_info.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"> <!-- これを足す -->
    <script src="../jspsych-6.3.1/jspsych.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-survey-text.js"></script>
    <script src="../jspsych-6.3.1/plugins/jspsych-survey-multi-choice.js"></script>
    <link rel="stylesheet" href="../jspsych-6.3.1/css/jspsych.css"></link>
  </head>
  <body></body>
  <script>
    var par_id = {
      type: 'survey-text',
      questions: [
        {prompt: '参加者IDを入力してください', columns: 10, required: true, name: 'participantID'},
      ],
      button_label: '次へ',
    };

    var age = {
      type: 'survey-text',
      questions: [
        {prompt: '年齢を入力してください', columns: 3, required: true, name: 'age'},
      ],
      button_label: '次へ',
    };

    var gender = {
      type: 'survey-multi-choice',
      questions: [
        {prompt: "性別を選択してください", options: ['男性', '女性'], required: true, horizontal: true, name: 'gender'},
      ],
      button_label: '次へ',
    };

    jsPsych.init({
      timeline: [par_id, age, gender],
      on_finish: function() {
        jsPsych.data.get().localSave('csv', 'data.csv');
      },
    });
  </script>
</html>

全部で 3 ページの実験(?)プログラムが実行されたはずです。まず,重要な点として,質問文に日本語を使っているので<head>の直後に<meta charset="utf-8">が挿入されています(第 2 章参照)。

それでは本題です。survey-textsurvey-multi-choiceのどちらもquestions:がメインの設定項目になります。どちらもquestions:[][]内に質問の内容や解答欄・選択肢に関する設定が記述されたオブジェクトが入っています。質問の設定項目はsurvey-textsurvey-multi-choiceでそれぞれ以下のようになります。

  • survey-text
    • prompt: 質問文
    • columns: 入力用のテキストボックスの幅
    • required: 解答必須かどうか
    • name: あとでデータを参照する際の名前
  • survey-multi-choice
    • options: 選択肢。配列[]で指定する。
    • horizontal: 選択肢を横向きに並べるか(falseなら縦向きに並べる)
    • prompt, required, name: 同上

requiredで回答を必須にしていないと無回答で次に進めてしまうので,参加者情報を集める場合に限っては常にtrueでいいでしょう。

なお,questionsは複数形になっている通り,[]内に質問用の設定オブジェクトを複数持ってくることができます。その場合,1 つのページに 2 つ以上の質問を提示することができます。適宜利用してください。参加者 ID と年齢の聞き取りには同じプラグインsurvey-textを利用しているので,以下のように一つの試行変数にまとめることができます。

var parID_age = {
  type: 'survey-text',
  questions: [
    { prompt: '参加者IDを入力してください', columns: 10, required: true, name: 'participantID' },
    { prompt: '年齢を入力してください', columns: 3, required: true, name: 'age' },
  ],
  button_label: '次へ',
};

回答の保存方法をアレンジする

次に,回答が保存されたファイルを確認してみましょう。responseという列に回答が保存されていますが,困ったことに{"participantID":"hogehoge"}のように JSON 形式(オブジェクト)で保存されてしまっています。これでは分析しにくいので,回答の部分だけを取り出して別の列に保存してみます[1]

個人的に一番シンプルだと思う方法は,回答の終了時にその回答を別の変数に取り出しておいて,最後にjsPsych.data.addProperties()でデータに追加するというものです。第 6 章では,on_finishという項目にfunction(data) {...}で処理を指定することで,各試行の終了時に反応の正誤などを判定する方法を紹介しました。同様にして今回は回答を取り出す処理を実装します。

var par_info = {}; // 一時保存用の変数(はじめは空)

var par_id = {
  type: 'survey-text',
  questions: [{ prompt: '参加者IDを入力してください', columns: 10, required: true, name: 'participantID' }],
  on_finish: function (data) {
    par_info.id = data.response.participantID; // 一時保存
  },
};

// その他の質問については省略

jsPsych.init({
  timeline: [par_id, age, gender],
  on_finish: function () {
    jsPsych.data.addProperties(par_info); // すべての行に追加
    jsPsych.data.get().localSave('csv', 'data.csv');
  },
});

第 6 章で扱ったように,data.response.participantIDで回答を取り出しています。.participantIDの部分,質問項目の設定name:で指定した文字列に一致します。nameを設定しなかった場合はQ0になります。

続いて,取り出した回答をpar_info.id =とすることで,事前に作った変数var par_info = {}に一時保存しています。そして,par_infoに保存しておいた情報はjsPsych.init()on_finishjsPsych.data.addProperties(par_info)として,データのすべての行に追加しています。

前回の記事では,on_finish: function(data) {...}の中でdata.新しい列名 = 値とすることで,任意の値を新しい列に保存できることを紹介しました。同様に今回も,data.id = data.response.participantIDとして保存しても構わないのですが,その場合参加者 ID はたった 1 行にしか保存されません(試してみてください)。

データの全行に参加者情報を追加するかは好みが分かれるところかもしれません。少なくとも参加者 ID は全行に保存しておかないと分析が面倒になると思います。性別や年齢はケースバイケースですが,実験の目的変数の分析に性別などの参加者情報を利用する場合は全行に保存されている方がいいと思います。

演習

  • 残りの質問の回答を一時保存するコードも書いてみよう
コード例

data.response.XXで取り出す際,XXは質問の設定で指定したnameに一致している必要があることに気をつけましょう。指定していない場合はどのon_finishでも.Q0とすればよいです。

par_info.XXpar_infoに回答を一時保存するときのXXは質問ごとに変えるようにしましょう。変えないと,回答が上書きされて,最後の質問の回答しか保存されなくなります。

var par_info = {};

var par_id = {
  type: 'survey-text',
  questions: [{ prompt: '参加者IDを入力してください', columns: 10, required: true, name: 'participantID' }],
  button_label: '次へ',
  on_finish: function (data) {
    par_info.id = data.response.participantID; // 一時保存
  },
};

var age = {
  type: 'survey-text',
  questions: [{ prompt: '年齢を入力してください', columns: 3, required: true, name: 'age' }],
  button_label: '次へ',
  on_finish: function (data) {
    par_info.age = data.response.age; // 一時保存
  },
};

var gender = {
  type: 'survey-multi-choice',
  questions: [{ prompt: '性別を選択してください', options: ['男性', '女性'], required: true, horizontal: true, name: 'gender' }],
  button_label: '次へ',
  on_finish: function (data) {
    par_info.gender = data.response.gender; // 一時保存
  },
};

jsPsych.init({
  timeline: [par_id, age, gender],
  on_finish: function () {
    jsPsych.data.addProperties(par_info); // すべての行に追加
    jsPsych.data.get().localSave('csv', 'data.csv');
  },
});

ランダムな参加者 ID を割り当てる

本章ではこれまで参加者 ID を入力できるようにしていました。対面実験をする場合はこれでいいのですが,オンライン実験をする場合には特別な事情がない限り,参加者 ID はランダムなものを割り当てるのがいいでしょう。

ありがたいことに,jsPsych にはランダムな ID を生成する関数jsPsych.randomization.randomID()が用意されています。この関数は引数に指定した数字の長さのランダムな文字列を生成します。

// 実行ごとに結果は変わる
jsPsych.randomization.randomID(12); // 0pu18xqt8ws6

参加者 ID を尋ねる質問部分をこの関数に置き換えてしまえばよいです。なんなら,一時保存用のpar_infoを宣言した時点で含めておいてもよいです。

var par_info = {
  id: jsPsych.randomization.randomID(12);
}

おわりに

本章では参加者情報の取得について紹介しました。on_finishでは他で宣言しておいた変数にある試行の結果を保存しておくことができます。今回紹介した,参加者情報の一時保存以外にも色んな場面で活用できます。例えば,各試行の反応時間を収集しておけば,どこかのタイミングで平均反応時間を使った処理の分岐ができたりします。実験を作る際にはそういう選択肢があるということを頭の片隅に置いておくと良いと思います。

脚注
  1. データ分析でよく使われる R や Python なら JSON 形式のデータを扱うためのライブラリやパッケージが提供されているので,この節で紹介している処理は必ずしも必要ではありません 。むしろ保存データに余分に参加者情報が保存されることになります。 ↩︎