[ 基本プログラム| 拡張1 | 拡張2 | 拡張3 | 拡張4]


これまでのプログラムでは毎試行乱数を振って報酬の有無を決めていますが,あらかじめ決めた割合で報酬が出る系列をシャッフルした方が参加者間の報酬割合のばらつきが抑えられます。

以下のような流れで事前に決めた報酬の系列を用いることができます。

  1. まずはRなどで報酬の系列を生成し,行方向を試行,列方向を各選択肢に割り当てらえた報酬とする テキストファイルを作ります。
  2. そのファイルをPsyToolkitのexperiment上でアップロードします。
  3. experimentのコード内でそのファイルをtableとして読み込みます。
  4. コードのtask内で,第n試行目ではtableはn行目が読まれ,その1列目は'@1’,2列目は'@2'という変数として参照します

exp_2armed_bandit_ext2

まず,Rで以下のようなスクリプトで各選択肢の報酬系列を決めるテキストファイルを作ります。

# 乱数のシードの設定
set.seed(1)

pr_good <- 0.7 # good optionの報酬確率
pr_bad <- 0.3  # bad optionの報酬確率

T <- 40 # 試行数

# pr_* の割合で1 (報酬あり),1-pr_*の割合で0 (報酬なし)となる数列を作る
Rgood <- rep(c(0,1), times = c(round( T * (1-pr_good)), round( T * pr_good)))
Rbad <- rep(c(0,1), times = c(round( T * (1-pr_bad)), round( T * pr_bad)))

# シャッフルする
Rgood <- sample(Rgood)
Rbad <- sample(Rbad)

# データフレームに格納
df <- data.frame(optionA = Rgood, optionB = Rbad)

# テキストファイルに書き出す
write.table(df, "reward_seq.txt", 
            quote=F, 
            sep=" ", 
            row.names=F, 
            col.names=F)

生成した系列は以下のようになります。

print(df)
##    optionA optionB
## 1        0       1
## 2        1       0
## 3        1       1
## 4        1       0
## 5        0       0
## 6        1       0
## 7        1       0
## 8        1       0
## 9        1       0
## 10       0       0
## 11       0       0
## 12       0       0
## 13       1       0
## 14       1       0
## 15       1       0
## 16       1       0
## 17       1       0
## 18       1       0
## 19       0       1
## 20       1       0
## 21       1       0
## 22       0       0
## 23       0       1
## 24       0       1
## 25       1       0
## 26       1       0
## 27       0       0
## 28       1       0
## 29       1       1
## 30       0       1
## 31       1       1
## 32       1       1
## 33       1       1
## 34       1       0
## 35       0       0
## 36       1       0
## 37       1       1
## 38       1       0
## 39       1       0
## 40       1       1
options
  mouse on # マウス入力をオン

fonts
  arial 36 # 使用するテキストのフォントを設定

# 【追加】tableとしてreward_seq.txtを読み込む -----------------------------------
table reward_seq
  include reward_seq.txt
  
# taskの1試行の流れを以下に記述
task 2armed_bandit
  # 【追加】各選択肢の報酬の系列の読み込み
  table reward_seq
  # 固視点の呈示 -----------------------------------
  #
  show text "+" 0 0 # -> stimulus 1に
  delay 1000
  clear 1 # stimulus 1 (固視点) を消す
  #
  # 選択肢の位置を決める ----------------------------
  #
  set $option_pos random 1 2
  if $option_pos == 1
    # 緑が右,青が左
    set $green_x 150
    set $blue_x -150
  fi
  if $option_pos == 2
    # 緑が左,青が右
    set $green_x -150
    set $blue_x 150
  fi
  #
  # 選択肢の呈示 -------------------------------------------
  #
  # 座標x = $green_x, y = 0の位置に,幅50,高さ50の緑の正方形を呈示
  show rectangle $green_x 0 50 50 0 255 0 # ⇒ stimulus 2に
  # 座標x = $blue_x, y = 0の位置に,幅50,高さ50の青の正方形を呈示
  show rectangle $blue_x 0 50 50 0 0 255 # ⇒ stimulus 3に
  #
  # マウスでの選択の読み取り -------------------------------
  #
  # stimulus 2 (緑の正方形),またはstimulus 3 (青の正方形)
  # が左クリックされるまで待つ
  # 【変更】固視点がstimulus 1となった分 stimulus IDが一つずれる
  # 制限時間は2000ms
  readmouse l 1 2000 range 2 3
  #
  # $c_pos にはクリックされたstimulusのID (2 or 3) が入る
  set $c_pos bitmap-under-mouse MOUSE_X MOUSE_Y
  #
  # 反応時間の記録
  set $decisiontime RT
  #
  #  2秒以内に反応がなかった場合のメッセージ ----------------
  #  制限時間以内にマウス入力がなかった場合,変数STATUSはTIMEOUT (=3) となる
  if STATUS == TIMEOUT  
    clear 2 3
    set $a 0 # 反応ミス -> $a = 0とする
    show text "2秒以内に選択してください!" 0 0
    delay 2500
  fi
  #
  #  どちらの選択をしたか判定 ---------------------------
  #
  if STATUS != TIMEOUT
    if $c_pos == 2    # 青い四角を選択
      set $a 1
    fi
    if $c_pos == 3    # 緑の四角を選択
      set $a 2
    fi
  fi
  #
  # 選択の結果の決定,呈示 ---------------------------------
  #
  # 報酬の有無の決定のため,1から100の間の乱数を生成
  set $x random 0 100
  if $a == 1 # 選択肢1 (緑) を選択
    show text "▲" $green_x  60
    delay 500
    # 
    # 【変更】
    if @1 == 1 # tableの1列目 (行は現在の試行ID)が1
      show text "+10ポイント" 0 -100
      set $reward 1
    fi 
    if @1 == 0 # tableの1列目 (行は現在の試行ID)が0
      show text "+0ポイント" 0 -100
      set $reward 0
    fi 
  fi
  if $a == 2 # 選択肢2 (青) を選択
    show text "▲" $blue_x  60
    delay 500
    # 
    # 【変更】
    if @2 == 1 # tableの1列目 (行は現在の試行ID)が1
      show text "+10ポイント" 0 -100
      set $reward 1
    fi 
    if @2 == 0 # tableの1列目 (行は現在の試行ID)が0
      show text "+0ポイント" 0 -100
      set $reward 0
    fi 
  fi
  # 1秒待つ
  delay 1000
  #
  # 1試行分のデータの保存-----------------------------------
  # 1列目: 反応時間 (選択肢が出てからキーを押すまで)
  # 2列目: 選択 (1 or 2)
  # 3列目: 報酬の有無 (0 or 1)
  # 4列目: 選択肢の位置 (1:緑が右, 2:緑が左)
  # 5列目: 選択肢1に割り当てられた報酬 (1 or 2) 【この列を追加】
  # 6列目: 選択肢2に割り当てられた報酬 (1 or 2) 【この列を追加】
  save $decisiontime $a $reward $option_pos @1 @2

block main
  tasklist
    # タスク2armed_banditを40試行行う
    # 【変更】デフォルトだと試行の順番はランダマイズされる
    # ので,ここではtableとして指定した報酬系列の順番通りに報酬を出すよう,
    # オプション 'fixed' をつける
    2armed_bandit 40 fixed
  end