jsPsychで作成した実験をQualtricsに埋め込んでWebで実行する方法・Rによるデータ読み込み

jsPsychで作成した実験をQualtricsに埋め込んでWebで実行する方法・Rによるデータ読み込み

2020年10月29日

jsPsychで作成した実験を、Qualtricsに埋め込んで実行する方法の紹介です。既に小林さんが「jsPsychの実験をQualtricsに貼り込む」という記事を作成されており、殆どはそちらと同じです。そちらを自分なりにまとめ直した半分備忘録です。

こちらだけでも完結しますが、以下の記事に依拠する部分が多いので、下記サイトのアクセスアップに貢献してから、こちらを御覧ください。

独自のポイントとしては、GitHubではなく「自サーバー(レンタルサーバー)でも動作する」の確認を行った点と「Rによるデータ読み込み方法」の2点。

必要なモノ・全体の流れ

  1. jsPsychのHTMLファイルを編集・分割
  2. サーバーにアップロード
  3. Qualtrics上の設定

大きく分けてやらなければならないことは上記の3つ。まずjsPsychのファイルを抽出し分割します。ここで必ず作成しなければならないのが「main.js」ファイルと呼ばれる実験のコアとなる部分。これと画像などをサーバーにアップロードし、jsPsychのプラグインやCSSをQualtricsで呼び出すための設定を行えば完成。

RとjsPsychで質問紙調査を作る、テキスト入力・リッカート・多肢選択の作成方法
心理学実験を行うツールはPsychoPyを始めとして様々なツールがありますが、オンラインで実験したりするにはハードルが高め。 反応時間が全て取得できて、クラウド…
kscscr.com

既にRMarkdownなどでjsPsychのHTMLファイルの作成が終了しているものとして話を進めます。

実験プログラムをQualtrics様に編集する

main.jsの作成

RMarkdownで作成しknitした、「experiment.html」というファイルが作成されている状態からスタートします。

//この上にはheadタグなど
.
.
<script src="jspsych-6.1.0/jspsych.js"></script>
<script src="jspsych-6.1.0/plugins/jspsych-instructions.js"></script>
<script src="jspsych-6.1.0/plugins/jspsych-html-keyboard-response.js"></script>
<script src="jspsych-6.1.0/plugins/jspsych-iat-html.js"></script>
<script src="jspsych-6.1.0/plugins/jspsych-fullscreen.js"></script>
<script type="text/javascript">

//!ここから!

//教示文を読んで入力してもらう
var iat_instruction_test = {
  type: "html-keyboard-response",
  stimulus:"<img src='Picture03.png' width='60%'>"+"<p style = 'font-size:1.5em; text-align: center'>練習です</p>"+"<p>キーボードを利用した単語の分類課題を行います。</p>"+"<p>画面中央に表示される単語が、左上の<b>「よい」</b>または<b>「虫」</b>のカテゴリーに当てはまると思ったら<b>「E」</b>キーを、<br>右上の<b>「わるい」</b>のカテゴリーに当てはまると思ったら<b>「I」</b>キーを押してください。</p>"+ "<p><b>左右のカテゴリーは固定で、中央の単語が変わります。</b></p>"+"<p>間違えるとX(バツ)が中央に表示されるので、押したキーと反対のキーを押してください</br><b>スペースキー</b>を押すと開始します。</p>"+"<p style = 'font-size: 1.5em;'>単語が表示されたら、なるべく早く回答してください。</p>",
  choices: ["space"]
};
.
.
.//実験内容が書いてある
.
.
timeline.push(endmessage);

//!ここまで!

/* 実験開始 */
jsPsych.init({
    timeline: timeline
});

</script>

VSCodeなどお好みのエディタで、新規に「main.js」というファイルを作成します。main.jsにjsPsychのJavascriptの部分、上記がexperiment.htmlファイルだとすると、「!ここから!」から「!ここまで!」に相当する部分をコピペします。「<script type=”text/javascript”>」タグのうち、「jsPsych.init」を除く部分まで全てになります。

main.jsの画像のパスを変更

var repo_site = "https://自分のサーバーのアドレス/フォルダ名/";

次に、main.js内の画像のパスを変更します。main.js内に画像のファイルを置いたURLを変数名として保存。一番上に上の一行を追加しましょう。自サーバーに保存する場合とGitHubにアップする場合でそれぞれ上のリンクは改変してください。

  //教示文を読んで入力してもらう
  var iat_instruction_test = {
    type: "html-keyboard-response",
    stimulus:"<img src='" + repo_site + "Picture03.png' width='60%'>"+"<p style = 'font-size:1.5em; text-align: center'>練習です</p>"+"<p>キーボードを利用した単語の分類課題を行います。</p>"+"<p>画面中央に表示される単語が、左上の<b>「よい」</b>または<b>「虫」</b>のカテゴリーに当てはまると思ったら<b>「E」</b>キーを、<br>右上の<b>「わるい」</b>のカテゴリーに当てはまると思ったら<b>「I」</b>キーを押してください。</p>"+ "<p><b>左右のカテゴリーは固定で、中央の単語が変わります。</b></p>"+"<p>間違えるとX(バツ)が中央に表示されるので、押したキーと反対のキーを押してください</br><b>スペースキー</b>を押すと開始します。</p>"+"<p style = 'font-size: 1.5em;'>単語が表示されたら、なるべく早く回答してください。</p>",
    choices: ["space"]
  };

main.js内にある画像を、さっき設定した変数名を含む形へ、つまり画像のリンクを

//こっちから
<img src='" + repo_site + "Picture03.png' width='60%'>
//こっちへ下
<img src='" + repo_site + "Picture03.png' width='60%'>

の様に設定しなおしましょう。

experiment_updated.htmlの作成

<script src="main.js"></script>

experiment.htmlを複製し、「experiment_updated.html」というファイルを作成します。experiment_updated.htmlから、先程main.jsでコピーした部分を削除します。上の記述をそのファイルのjsPsychを読み込んでいる部分に追加します。

ここでローカルでexperiment_updated.htmlをダブルクリックして問題なく実験を行うことができればOK。これはあくまでmain.jsが動作するかどうかを確認するためのファイル。データが保存されているかどうかは気にしなくて大丈夫です。

jsPsychの実験をサーバーに置く


ここまで来たらサーバーにファイルを設置します。main.jsとjsPsych本体、画像をFTPクライアントなどを使ってアップロードします。アクセスできれば自分が運営しているWordPressをインストールしているサーバーにサブドメインなどを作ってそこにおいてしまうのもいいでしょう。

Qualtrics.jsの準備

Qualtrics.SurveyEngine.addOnload(function()
{
    /*Place your JavaScript here to run when the page is fully displayed*/
    var qthis = this;
    qthis.hideNextButton();

    var task_github = "https://自分のサーバーのアドレス/フォルダ名/""; 

    var requiredResources = [
        task_github + "jspsych-6.1.0/jspsych.js",
        task_github + "jspsych-6.1.0/plugins/jspsych-html-keyboard-response.js",
        task_github + "jspsych-6.1.0/plugins/jspsych-image-keyboard-response.js",
        task_github + "main.js"
    ];

    function loadScript(idx) {
        console.log("Loading ", requiredResources[idx]);
        jQuery.getScript(requiredResources[idx], function () {
            if ((idx + 1) < requiredResources.length) {
                loadScript(idx + 1);
            } else {
                initExp();
            }
        });
    }

    if (window.Qualtrics && (!window.frameElement || window.frameElement.id !== "mobile-preview-view")) {
        loadScript(0);
    }

    jQuery("<div id = 'display_stage_background'></div>").appendTo('body');
    jQuery("<div id = 'display_stage'></div>").appendTo('body');
    
    function initExp() {
        jsPsych.init({
            timeline: timeline,
            display_element: 'display_stage',
            on_finish: function (data) {
      
                  var datajs = jsPsych.data.get().json();
                
                Qualtrics.SurveyEngine.setEmbeddedData("datajs", datajs);
        
                jQuery('display_stage').remove();
                jQuery('display_stage_background').remove();
        
                qthis.clickNextButton();
            }
        });
      };
});

Qualtrics.SurveyEngine.addOnReady(function()
{
    /*Place your JavaScript here to run when the page is fully displayed*/

});

Qualtrics.SurveyEngine.addOnUnload(function()
{
    /*Place your JavaScript here to run when the page is unloaded*/

});

新規ファイルとして「qualtrics.js」というファイルを作成し、task_githubの部分は適宜、自分がファイルを置くリンクの場所に変更してください。これは後でQualtrics上にコピペします。

内容については上のサイトで詳しく紹介されています。

Qualtrics上での設定

qualtrics
新しい質問を作成し、質問タイプを「テキスト/グラフィック」にします。テキストを編集画面に切り替え、リッチコンテンツエディターからhtmlの編集モードに切り替えます。

<link href="https://自分のサーバーのアドレス/フォルダ名/jspsych-6.1.0/css/jspsych.css" rel="stylesheet" type="text/css" /><br />
<br />
<span style="font-size: 24px;">もしこのメッセージが <span style="color: rgb(255, 0, 0);"><b>5分以上表示されていたら、</b></span>,<br />
お手数ですが管理者までご連絡ください。 </span><br />
<br />
<style type="text/css">#display_stage_background {
      width: 100vw;
      background-color: white;
      z-index: -1;
  }

  #display_stage {
      position: fixed;
      left: 1vw;
      top: 1vh;
      height: 98vh;
      width: 98vw;
      background-color: white;
      box-shadow: 1px 1px 1px #999;
      border-radius: 15px;
      z-index: 0;
      overflow-y: hidden;
      overflow-x: hidden;
  }
</style>

そしてそこに上記の内容をペースト。一番上のリンクは自分のものに合わせて改変しましょう。

qualtrics
後は、横にある歯車アイコンをクリックし、「javascriptを追加」を選択、 中身をすべて消しqualtrics.jsで記述した内容をコピペすればOK。

アンケートフローの設定

qualtrics
アンケートフローをクリックし、IATのブロックの下に「埋め込みデータ」を追加します。「新しいフィールド名を定義するか、ドロップダウンから選択」に「datajs」と入力し保存します。

これでQualtrics上でIATを実行できるようになります。

GitHubに置く場合

GitHub
自前のレンタルサーバーではなく、GitHubにおいて実行する場合、該当レポジトリのSetting→Option→GitHub Pageの部分を上記のように設定しておかないと、設定したリンクにファイルをおいても実行されないので注意が必要です。

ちなみにこの記事で紹介していたmain.jsなどの「https://自サーバー」の部分は「https://ユーザー名.github.io/レポジトリ名/」に変更する必要があります。

Rでデータを分析する

library(jsonlite)
library(tidyverse)
library(formattable)

# データの読み込み
dat <- read.csv("test.csv", header =T)

# 必要な列の抜き出し
js_dat <- dat %>% 
  dplyr::select(code, datajs)
js_data <- tibble()

#Qualtricsで
for(i in 1:nrow(dat)){
    #Qualtricsから出力されたもののうちjsPsychのデータを抽出
    tidy_df01 <- js_dat[i, 2]
    #txtとして書き出し
    write.table(tidy_df01, "output.txt", quote = F, col.names=F, row.names = F, append=F)
    #jsonとして読み込み整理
    tidy_df02 <- fromJSON("output.txt") %>% 
      as_tibble(validate = F) %>% 
      #IDをつけて
      mutate(code = js_dat[i, 1])
    #他の参加者と結合する
    if(i == 1){
      js_data <- tidy_df02
    }else{
      js_data <- union(js_data, tidy_df02)
    }
}

Qualtricsに保存されたデータでは基本的に、csvのファイルの一つのセルの中に参加者のjsPsychのデータすべてが保存されます。そのため普通にcsvファイルを読み込んでも操作出来ません。
そのため、参加者一人ずつ、csvの中のdatajsのセルをテキストファイルに抽出し、jsonliteパッケージを用いて読み込み、R上で全参加者を結合するという手順を踏む必要があります。