心理学実験を行うツールはPsychoPyを始めとして様々なツールがありますが、オンラインで実験したりするにはハードルが高め。
反応時間が全て取得できて、クラウドソージングサービスなどとも連携できる良いツールとして、TokyoRでRとjsPsychを利用した発表をされているのを見て、実際に作ってみました。実際に実験の画面などの画像は記事の一番最後に追加しています。
この記事はando_Roid(@hirahira2835)と国里先生のページを主にもとにして作成しています。
この記事は、別の記事で紹介する導入として、RとjsPsychについて触れています。上のサイトで紹介されているスライドは非常に綺麗でわかりやすいので、見たほうが良いです。
目次
Rで実験を作るとは?
HTMLとCSSがわかって、Javascriptが書けるのであれば、Rmarkdownを利用する必要はありません。
ただ「JavaScriptやHTML・CSSを書けるの?」という問題。これらをすべて一気にやるのは、ちょっとハードルが高いですし、すぐにはできません。
そこで、RMarkdownを使って、HTMLを書いたりするのはRにやってもらって、実験刺激をjsPsychで頑張って書こうというのが、「Rでやる」という意味です。
RでjsPsychを始める準備
RStudioで新規にプロジェクトを作成します。
作成が完了したらjsPsychのリリースページから、”jspsych-6.1.0.zip”をダウンロードします。ダウンロードをしたら、zipファイルを解凍して、先程のプロジェクトと同じフォルダに移動します。
あとはRStudioで新規のRMarkdownファイルを作成すれば前準備は完了。あとは実験を作成していくだけになります。
OverView
さてここからR Markdownで早速IATを実装するのですが、ファイルの中に記入することは大きく4つに分けられます。
- yamlヘッダー・setupチャンク:RMarkdownの設定。基本的に毎回コピペ。記入することは変わらない
- jsPsychプラグイン:jsPsychのライブラリから必要なもの読み込む。作る実験課題によって変わる
- 実験課題:実験課題によって書く内容は異なります。
yamlヘッダー、setupチャンク、jsPsychプラグイン、実験課題の4つがメインとなる項目。といっても最初の2つは毎回コピペになりますし、jsPsychプラグインもほとんどコピペ、実質プログラムを書くのは実験課題だけです。
yamlヘッダー、setupチャンク、jsPsychプラグイン
output: html_document: mathjax: null highlight: null theme: null css: jspsych-6.1.0/css/jspsych.css
yamlヘッダーについては、画像の用に”output”の部分に上記の項目をコピペします。”6.1.0″の部分については自分が使用するバージョンに合わせて改変しましょう。
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE)
setupチャンクには、上記のコードを追加。rチャンクのコードやメッセージや警告がでても非表示にするようなデフォルト設定にしています。
library(htmltools) tagList( tags$script(src="jspsych-6.1.0/jspsych.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-html-keyboard-response.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-instructions.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-text.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-likert.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-multi-choice.js") )
次のrチャンクで、新たにjsPsychプラグインを読み込みます。今回は「説明」、「テキスト入力」、「リッカート尺度」「多肢選択形式」のためのjsファイルを読み込んでいます。どんなjsファイル(プラグイン)があるかについては、上でダウンロードしたフォルダの”plugins”を見るとわかります。
質問紙を作ろう
実験課題用のチャンクに書く内容は、実験内容、実験課題の順番、実験を開始するための設定の3つ。これらはすべて一つの{js}チャンクに入力します。
- 実験内容:リッカート、自由記述、IATなどの実験内容を書く。
- 実験課題の順番;上で作った実験の順番を指定する
- 実験を開始するための設定:データの保存など
実験内容
今回作成するのは「実験についての説明」→「テキスト入力」→「リッカート尺度」→「多肢選択形式」という流れで簡単な質問紙を作成してみたいと思います。
実験についての説明
//Instructionの表示 var instruction = { type: 'instructions', //実験タイプを設定 pages: ["<p>調査します。よろしくお願いいたします。</p>"], //表示する説明文を書く allow_backward: false, //前に戻るのを許可するかどうか show_clickable_nav: true, //次へのボタンを表示 button_label_next: "次へ" //次へのボタンラベルを変更(指定しないと"Continue"と表示される) };
実験のコードのベースは、説明文も、質問紙も、リッカートも同じ。基本的には”var {適当な名前} = {実験内容}”というフォーマット。
“type”で、調査や実験の種類を指定、残りの項目は使用するプラグインによって変わります。
varはJavascriptで変数の宣言に使われることが多く、変数を格納したり、実験課題の内容を格納するのに使います。
テキスト入力
var form_trial = { type: "survey-text", questions: [ {prompt: "何歳ですか?半角数字で入力してください", name: 'Age', required:"True"} ], button_label: "次へ"//次へのボタンラベルを変更(指定しないと"Continue"と表示される) };
“question”内の”prompt”で質問文を表示、”name”は変数名、”required”は強制回答にするかどうかです。
リッカート尺度
//選択肢の用意が必要 var scale_01 = [ "まったく当てはまらない", "あまり当てはまらない", "どちらともいえない", "やや当てはまる", "非常に当てはまる" ]; //リッカート尺度の質問課題を準備 var question_se = { type: 'survey-likert', questions: [ {prompt: "朝起きるのが難しい", labels: scale_01, required: "True"}, {prompt: "毎日がバラのようである", labels: scale_01, required: "True"}, {prompt: "私は人生において勝ち組である", labels: scale_01, required: "True"}, {prompt: "何をやってもうまくいかないことが多い", labels: scale_01, required: "True"}, ], button_label: "次へ" };
リッカート尺度に関しては、回答するためのラベルの準備と、実験課題用のブロックが必要。”labels”で上で作成したscale_01を指定します。
実験の順番
/* 実験の提示の順番 */ var timeline = []; timeline.push(instruction); timeline.push(form_trial); timeline.push(question_se);
上で作成したものを順番にしていしていきます。”timeline”という入れ物の中に、”instruction”, “form_trial”, “queston_se”の順番で入れていきます。並び替えれば表示順序が変わります。
実験を開始するための設定
/* 実験開始 */ jsPsych.init({ timeline: timeline, on_finish: function() { jsPsych.data.displayData(); } });
“timeline”に上で作成したtimelineを作成し、”on_finish”内で実験終了後にデータを画面に表示するように指定しています。
あとはknitするだけで実験は完成します。
すべて:実験コード
--- title: "test" author: "no name" date: "1/25/2020" output: html_document: mathjax: null highlight: null theme: null css: jspsych-6.1.0/css/jspsych.css --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) ``` ```{r} library(htmltools) tagList( tags$script(src="jspsych-6.1.0/jspsych.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-instructions.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-text.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-likert.js"), tags$script(src="jspsych-6.1.0/plugins/jspsych-survey-multi-choice.js") ) ``` ```{js} //Instructionの表示 var instruction = { type: 'instructions', pages: ["<p>調査します。よろしくお願いいたします。</p>" ], allow_backward: false, show_clickable_nav: true, button_label_next: "次へ" }; var form_trial = { type: "survey-text", questions: [ {prompt: "何歳ですか?半角数字で入力してください", name: 'Age', required:"True"} ], button_label: "次へ" }; var scale_01 = [ "まったく当てはまらない", "あまり当てはまらない", "どちらともいえない", "やや当てはまる", "非常に当てはまる" ]; var question_se = { type: 'survey-likert', questions: [ {prompt: "朝起きるのが難しい", labels: scale_01, required: "True"}, {prompt: "毎日がバラのようである", labels: scale_01, required: "True"}, {prompt: "私は人生において勝ち組である", labels: scale_01, required: "True"}, {prompt: "何をやってもうまくいかないことが多い", labels: scale_01, required: "True"}, ], button_label: "次へ" }; /* 実験の提示の順番 */ var timeline = []; timeline.push(instruction); timeline.push(form_trial); timeline.push(question_se); /* 実験開始 */ jsPsych.init({ timeline: timeline, on_finish: function() { jsPsych.data.displayData(); } });
参考文献
実験画面
今回のコードで実験の画面がどの様になるのか画像を追加しました(追記:2020/02/14)。