【jsPsych】Rでsurvey系pluginの前処理



# よくある問題

- jsPsychでリッカートなどsurvey系のpluginを使って、実行すると以下のようなデータが得られる
ここでは、survey-likertを使った2人分のデータ。

```r
df
# A tibble: 2 × 8
  subject_id    rt response                                    question_order trial_type    trial_index time_elapsed internal_node_id
  <chr>      <dbl> <chr>                                       <chr>          <chr>               <dbl>        <dbl> <chr>           
1 mxpue       4315 "{\"Fruit\":0,\"Meat\":2,\"Vegetables\":4}" [1,2,0]        survey-likert           0         4318 0.0-0.0         
2 axp3k       3470 "{\"Meat\":4,\"Fruit\":2,\"Vegetables\":0}" [2,1,0]        survey-likert           0         3471 0.0-0.0     
```

- response列の中に質問項目と回答が含まれているため扱う際に面倒

# 解決方法
- response列は文字列型になっているが、実際はJSON形式で無理やり文字列型になっているだけなので、JSONで読み込んでやればよい。
- R(tidyverse+jsonlite)でやります。

```r
library(tidyverse)
library(jsonlite)
questionnaire <- df %>% 
  dplyr::filter(trial_type == "survey-likert") %>% ##今回はリッカートの部分だけ抽出
  dplyr::mutate(likert = purrr::map(.x = response,
                    .f = ~jsonlite::fromJSON(.x))) ##response列をJSONとして読み込み、それをlikert列とする

questionnaire
# A tibble: 2 × 9
  subject_id    rt response                                    question_order trial_type    trial_index time_elapsed internal_node_id likert          
  <chr>      <dbl> <chr>                                       <chr>          <chr>               <dbl>        <dbl> <chr>            <list>          
1 mxpue       4315 "{\"Fruit\":0,\"Meat\":2,\"Vegetables\":4}" [1,2,0]        survey-likert           0         4318 0.0-0.0          <named list [3]>
2 axp3k       3470 "{\"Meat\":4,\"Fruit\":2,\"Vegetables\":0}" [2,1,0]        survey-likert           0         3471 0.0-0.0          <named list [3]>
```

- named listになっているそうなので、データフレームに変換する

```r
questionnaire <- questionnaire %>% 
  dplyr::select(subject_id, likert) %>% 
  dplyr::group_by(subject_id) %>% ##idごとにグループ化しておかないと余計な列が増える
  dplyr::mutate(data.frame(likert)) ##リスト型をデータフレームに変換する

questionnaire
# A tibble: 2 × 5
# Groups:   subject_id [2]
  subject_id likert            Meat Fruit Vegetables
  <chr>      <list>           <int> <int>      <int>
1 mxpue      <named list [3]>     2     0          4
2 axp3k      <named list [3]>     4     2          0
```

## pre-postなど複数回同じ尺度を取ってる場合

```r
df
# A tibble: 4 × 9
  subject_id    rt response                                    question_order pre_post trial_type    trial_index time_elapsed internal_node_id
  <chr>      <dbl> <chr>                                       <chr>          <chr>    <chr>               <dbl>        <dbl> <chr>           
1 hnm5t       6367 "{\"Vegetables\":0,\"Meat\":2,\"Fruit\":4}" [0,2,1]        pre      survey-likert           0         6385 0.0-0.0         
2 hnm5t       4037 "{\"Vegetables\":4,\"Fruit\":2,\"Meat\":2}" [0,1,2]        post     survey-likert           1        10428 0.0-1.0         
3 f1a0f       4771 "{\"Fruit\":3,\"Vegetables\":3,\"Meat\":1}" [1,0,2]        pre      survey-likert           0         4773 0.0-0.0         
4 f1a0f       7997 "{\"Meat\":1,\"Vegetables\":3,\"Fruit\":3}" [2,0,1]        post     survey-likert           1        12774 0.0-1.0 

```

- プレポスなどの場合はjsPsych側でそのことを記録しているはずなので(今回の場合は5列目のpre_post列)、それについても`group_by()`してやればよい。

```r
questionnaire <- df %>% 
  dplyr::filter(trial_type == "survey-likert") %>% 
  dplyr::mutate(likert = purrr::map(.x = response,
                                    .f = ~jsonlite::fromJSON(.x)))
##ここはさっきと全く同じ
```


```r
questionnaire <- questionnaire %>% 
  dplyr::select(subject_id, pre_post,likert) %>% 
  dplyr::group_by(subject_id, pre_post) %>% ##pre_post列も一緒にgroup_byする
  dplyr::mutate(data.frame(likert))

questionnaire
# A tibble: 4 × 6
# Groups:   subject_id, pre_post [4]
  subject_id pre_post likert            Meat Vegetables Fruit
  <chr>      <chr>    <list>           <int>      <int> <int>
1 hnm5t      pre      <named list [3]>     2          0     4
2 hnm5t      post     <named list [3]>     2          4     2
3 f1a0f      pre      <named list [3]>     1          3     3
4 f1a0f      post     <named list [3]>     1          3     3
```

- これで参加者・プレポストごとに整形できる

- 他にうまいやり方があったら教えてください。