In this document, I will show you how to transform data obtained in the jsPsych experiment into a format that can be used for analysis in R. The output from the jsPsych experiment is JSON format, which is not suitable for analysis in R. Therefore, we need to convert the JSON data into a format that can be used for analysis in R.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(jsonlite)
##
## Attaching package: 'jsonlite'
##
## The following object is masked from 'package:purrr':
##
## flatten
dat <- fromJSON("sample-data-output.txt")
head(dat,20)
## rt
## 1 906
## 2 644
## 3 270
## 4 330
## 5 284
## 6 315
## 7 330
## 8 299
## 9 300
## 10 465
## 11 435
## 12 1500
## 13 NA
## 14 278
## 15 270
## 16 300
## 17 300
## 18 255
## 19 285
## 20 270
## stimulus
## 1 \n <div style="text-align: left;">\n <h2>Self-Paced Reading Demo</h2>\n \n <p>In this demo, you will see sentences presented one word at a time using the self-paced reading paradigm.</p>\n \n <p>Lines representing the number of words will be displayed on the screen.\n Pressing the space bar will reveal the words one by one. \n Continue pressing the space bar to advance to the next word.</p>\n \n <p>After each sentence, a comprehension question will follow.\n Press the <strong>F key for YES</strong> and the <strong>J key for NO</strong>.</p>\n \n <p>Press the space bar to begin a brief practice session.</p>\n </div>
## 2 <div class="target">___ ____ ___ ____ ____ ______ ___ _______ _______</div>
## 3 <div class="target">The ____ ___ ____ ____ ______ ___ _______ _______</div>
## 4 <div class="target">___ shop ___ ____ ____ ______ ___ _______ _______</div>
## 5 <div class="target">___ ____ has ____ ____ ______ ___ _______ _______</div>
## 6 <div class="target">___ ____ ___ only ____ ______ ___ _______ _______</div>
## 7 <div class="target">___ ____ ___ ____ five ______ ___ _______ _______</div>
## 8 <div class="target">___ ____ ___ ____ ____ tables ___ _______ _______</div>
## 9 <div class="target">___ ____ ___ ____ ____ ______ for _______ _______</div>
## 10 <div class="target">___ ____ ___ ____ ____ ______ ___ selling _______</div>
## 11 <div class="target">___ ____ ___ ____ ____ ______ ___ _______ fruits.</div>
## 12 Does the shop have more than five tables?
## 13 <p style='font-size: 40px; color: red;'>INCORRECT</p>
## 14 <div class="prepare">Prepare for the next trial. Press the space bar to proceed to the next sentence.</div>
## 15 <div class="target">___ _________ ____ _____ ___ ____ ______ ____ ___ ________</div>
## 16 <div class="target">The _________ ____ _____ ___ ____ ______ ____ ___ ________</div>
## 17 <div class="target">___ professor ____ _____ ___ ____ ______ ____ ___ ________</div>
## 18 <div class="target">___ _________ will _____ ___ ____ ______ ____ ___ ________</div>
## 19 <div class="target">___ _________ ____ grade ___ ____ ______ ____ ___ ________</div>
## 20 <div class="target">___ _________ ____ _____ the ____ ______ ____ ___ ________</div>
## response trial_type trial_index time_elapsed internal_node_id
## 1 html-keyboard-response 0 909 0.0-0.0
## 2 html-keyboard-response 1 1554 0.0-1.0-0.0
## 3 html-keyboard-response 2 1824 0.0-1.0-1.0
## 4 html-keyboard-response 3 2155 0.0-1.0-2.0
## 5 html-keyboard-response 4 2439 0.0-1.0-3.0
## 6 html-keyboard-response 5 2754 0.0-1.0-4.0
## 7 html-keyboard-response 6 3084 0.0-1.0-5.0
## 8 html-keyboard-response 7 3384 0.0-1.0-6.0
## 9 html-keyboard-response 8 3684 0.0-1.0-7.0
## 10 html-keyboard-response 9 4149 0.0-1.0-8.0
## 11 html-keyboard-response 10 4584 0.0-1.0-9.0
## 12 f html-keyboard-response 11 6084 0.0-1.0-10.0
## 13 <NA> html-keyboard-response 12 8086 0.0-2.0
## 14 html-keyboard-response 13 8364 0.0-3.0
## 15 html-keyboard-response 14 8634 0.0-4.0-0.0
## 16 html-keyboard-response 15 8934 0.0-4.0-1.0
## 17 html-keyboard-response 16 9234 0.0-4.0-2.0
## 18 html-keyboard-response 17 9489 0.0-4.0-3.0
## 19 html-keyboard-response 18 9774 0.0-4.0-4.0
## 20 html-keyboard-response 19 10044 0.0-4.0-5.0
## group trialNumber exp_item trialType itemID presented_word regionNumber
## 1 <NA> NA NA <NA> NA <NA> NA
## 2 practice 1 TRUE practice 1 <NA> NA
## 3 practice 1 TRUE practice 1 The 1
## 4 practice 1 TRUE practice 1 shop 2
## 5 practice 1 TRUE practice 1 has 3
## 6 practice 1 TRUE practice 1 only 4
## 7 practice 1 TRUE practice 1 five 5
## 8 practice 1 TRUE practice 1 tables 6
## 9 practice 1 TRUE practice 1 for 7
## 10 practice 1 TRUE practice 1 selling 8
## 11 practice 1 TRUE practice 1 fruits. 9
## 12 practice 1 TRUE practice 1 <NA> NA
## 13 <NA> NA NA <NA> NA <NA> NA
## 14 <NA> NA NA <NA> NA <NA> NA
## 15 practice 2 TRUE practice 2 <NA> NA
## 16 practice 2 TRUE practice 2 The 1
## 17 practice 2 TRUE practice 2 professor 2
## 18 practice 2 TRUE practice 2 will 3
## 19 practice 2 TRUE practice 2 grade 4
## 20 practice 2 TRUE practice 2 the 5
## sentence
## 1 <NA>
## 2 <NA>
## 3 <NA>
## 4 <NA>
## 5 <NA>
## 6 <NA>
## 7 <NA>
## 8 <NA>
## 9 <NA>
## 10 <NA>
## 11 <NA>
## 12 The shop has only five tables for selling fruits.
## 13 <NA>
## 14 <NA>
## 15 <NA>
## 16 <NA>
## 17 <NA>
## 18 <NA>
## 19 <NA>
## 20 <NA>
## comprehension_question correctAnswer correct condition
## 1 <NA> NA NA <NA>
## 2 <NA> NA NA <NA>
## 3 <NA> NA NA <NA>
## 4 <NA> NA NA <NA>
## 5 <NA> NA NA <NA>
## 6 <NA> NA NA <NA>
## 7 <NA> NA NA <NA>
## 8 <NA> NA NA <NA>
## 9 <NA> NA NA <NA>
## 10 <NA> NA NA <NA>
## 11 <NA> NA NA <NA>
## 12 Does the shop have more than five tables? FALSE FALSE <NA>
## 13 <NA> NA NA <NA>
## 14 <NA> NA NA <NA>
## 15 <NA> NA NA <NA>
## 16 <NA> NA NA <NA>
## 17 <NA> NA NA <NA>
## 18 <NA> NA NA <NA>
## 19 <NA> NA NA <NA>
## 20 <NA> NA NA <NA>
The following is the list of the variables in the data:
str(dat)
## 'data.frame': 135 obs. of 19 variables:
## $ rt : int 906 644 270 330 284 315 330 299 300 465 ...
## $ stimulus : chr "\n <div style=\"text-align: left;\">\n <h2>Self-Paced Reading Demo</h2>\n \n <p>In this demo,"| __truncated__ "<div class=\"target\">___ ____ ___ ____ ____ ______ ___ _______ _______</div>" "<div class=\"target\">The ____ ___ ____ ____ ______ ___ _______ _______</div>" "<div class=\"target\">___ shop ___ ____ ____ ______ ___ _______ _______</div>" ...
## $ response : chr " " " " " " " " ...
## $ trial_type : chr "html-keyboard-response" "html-keyboard-response" "html-keyboard-response" "html-keyboard-response" ...
## $ trial_index : int 0 1 2 3 4 5 6 7 8 9 ...
## $ time_elapsed : int 909 1554 1824 2155 2439 2754 3084 3384 3684 4149 ...
## $ internal_node_id : chr "0.0-0.0" "0.0-1.0-0.0" "0.0-1.0-1.0" "0.0-1.0-2.0" ...
## $ group : chr NA "practice" "practice" "practice" ...
## $ trialNumber : int NA 1 1 1 1 1 1 1 1 1 ...
## $ exp_item : logi NA TRUE TRUE TRUE TRUE TRUE ...
## $ trialType : chr NA "practice" "practice" "practice" ...
## $ itemID : int NA 1 1 1 1 1 1 1 1 1 ...
## $ presented_word : chr NA NA "The" "shop" ...
## $ regionNumber : int NA NA 1 2 3 4 5 6 7 8 ...
## $ sentence : chr NA NA NA NA ...
## $ comprehension_question: chr NA NA NA NA ...
## $ correctAnswer : logi NA NA NA NA NA NA ...
## $ correct : logi NA NA NA NA NA NA ...
## $ condition : chr NA NA NA NA ...
But first we need to remember that the task includes a practice section and a main task section. And in each trial, there is a sentence reading part and a comprehension question part.
First, we need to divide the data into practice and main task sections. This is because the practice section is usually not included in the analysis.
practice <- dat %>%
filter(trialType == "practice")
main_task <- dat %>%
filter(trialType == "main")
head(practice)
## rt
## 1 644
## 2 270
## 3 330
## 4 284
## 5 315
## 6 330
## stimulus
## 1 <div class="target">___ ____ ___ ____ ____ ______ ___ _______ _______</div>
## 2 <div class="target">The ____ ___ ____ ____ ______ ___ _______ _______</div>
## 3 <div class="target">___ shop ___ ____ ____ ______ ___ _______ _______</div>
## 4 <div class="target">___ ____ has ____ ____ ______ ___ _______ _______</div>
## 5 <div class="target">___ ____ ___ only ____ ______ ___ _______ _______</div>
## 6 <div class="target">___ ____ ___ ____ five ______ ___ _______ _______</div>
## response trial_type trial_index time_elapsed internal_node_id
## 1 html-keyboard-response 1 1554 0.0-1.0-0.0
## 2 html-keyboard-response 2 1824 0.0-1.0-1.0
## 3 html-keyboard-response 3 2155 0.0-1.0-2.0
## 4 html-keyboard-response 4 2439 0.0-1.0-3.0
## 5 html-keyboard-response 5 2754 0.0-1.0-4.0
## 6 html-keyboard-response 6 3084 0.0-1.0-5.0
## group trialNumber exp_item trialType itemID presented_word regionNumber
## 1 practice 1 TRUE practice 1 <NA> NA
## 2 practice 1 TRUE practice 1 The 1
## 3 practice 1 TRUE practice 1 shop 2
## 4 practice 1 TRUE practice 1 has 3
## 5 practice 1 TRUE practice 1 only 4
## 6 practice 1 TRUE practice 1 five 5
## sentence comprehension_question correctAnswer correct condition
## 1 <NA> <NA> NA NA <NA>
## 2 <NA> <NA> NA NA <NA>
## 3 <NA> <NA> NA NA <NA>
## 4 <NA> <NA> NA NA <NA>
## 5 <NA> <NA> NA NA <NA>
## 6 <NA> <NA> NA NA <NA>
head(main_task)
## rt
## 1 577
## 2 240
## 3 225
## 4 224
## 5 255
## 6 210
## stimulus
## 1 <div class="target">___ _________ ________ __ ___ ______ ______ ___ __ __ ___________</div>
## 2 <div class="target">The _________ ________ __ ___ ______ ______ ___ __ __ ___________</div>
## 3 <div class="target">___ defendant ________ __ ___ ______ ______ ___ __ __ ___________</div>
## 4 <div class="target">___ _________ examined __ ___ ______ ______ ___ __ __ ___________</div>
## 5 <div class="target">___ _________ ________ by ___ ______ ______ ___ __ __ ___________</div>
## 6 <div class="target">___ _________ ________ __ the ______ ______ ___ __ __ ___________</div>
## response trial_type trial_index time_elapsed internal_node_id
## 1 html-keyboard-response 28 16299 0.0-7.0-0.0
## 2 html-keyboard-response 29 16538 0.0-7.0-1.0
## 3 html-keyboard-response 30 16764 0.0-7.0-2.0
## 4 html-keyboard-response 31 16988 0.0-7.0-3.0
## 5 html-keyboard-response 32 17243 0.0-7.0-4.0
## 6 html-keyboard-response 33 17453 0.0-7.0-5.0
## group trialNumber exp_item trialType itemID presented_word regionNumber
## 1 target 1 TRUE main 1 <NA> NA
## 2 target 1 TRUE main 1 The 1
## 3 target 1 TRUE main 1 defendant 2
## 4 target 1 TRUE main 1 examined 3
## 5 target 1 TRUE main 1 by 4
## 6 target 1 TRUE main 1 the 5
## sentence comprehension_question correctAnswer correct condition
## 1 <NA> <NA> NA NA animate
## 2 <NA> <NA> NA NA animate
## 3 <NA> <NA> NA NA animate
## 4 <NA> <NA> NA NA animate
## 5 <NA> <NA> NA NA animate
## 6 <NA> <NA> NA NA animate
Next, we need to divide the data into sentence reading and comprehension question sections. This is because the accuracy of comprehension questions and the reading time of sentences are usually analyzed separately.
sentence_reading <- main_task %>%
filter(is.na(comprehension_question))
comprehension_question <- main_task %>%
filter(!is.na(comprehension_question))
Next, we need to extract the necessary variables from the data. The necessary variables are usually the subject ID (which is not relevant here because there is only one file), the trial number, the sentence, and the response time.
sentence_reading2 <- sentence_reading %>%
select(trialNumber, itemID, rt, regionNumber, condition, presented_word)
print(sentence_reading2)
## trialNumber itemID rt regionNumber condition presented_word
## 1 1 1 577 NA animate <NA>
## 2 1 1 240 1 animate The
## 3 1 1 225 2 animate defendant
## 4 1 1 224 3 animate examined
## 5 1 1 255 4 animate by
## 6 1 1 210 5 animate the
## 7 1 1 224 6 animate lawyer
## 8 1 1 241 7 animate turned
## 9 1 1 240 8 animate out
## 10 1 1 239 9 animate to
## 11 1 1 225 10 animate be
## 12 1 1 345 11 animate unreliable.
## 13 2 2 405 NA inanimate <NA>
## 14 2 2 225 1 inanimate The
## 15 2 2 225 2 inanimate gold
## 16 2 2 210 3 inanimate transported
## 17 2 2 224 4 inanimate by
## 18 2 2 210 5 inanimate the
## 19 2 2 225 6 inanimate guards
## 20 2 2 345 7 inanimate was
## 21 2 2 300 8 inanimate closely
## 22 2 2 315 9 inanimate watched.
## 23 3 3 270 NA animate <NA>
## 24 3 3 269 1 animate The
## 25 3 3 285 2 animate teacher
## 26 3 3 285 3 animate loved
## 27 3 3 285 4 animate by
## 28 3 3 284 5 animate the
## 29 3 3 269 6 animate class
## 30 3 3 301 7 animate was
## 31 3 3 284 8 animate very
## 32 3 3 314 9 animate easy
## 33 3 3 300 10 animate to
## 34 3 3 332 11 animate understand.
## 35 4 4 270 NA inanimate <NA>
## 36 4 4 344 1 inanimate The
## 37 4 4 255 2 inanimate bricks
## 38 4 4 285 3 inanimate lifted
## 39 4 4 285 4 inanimate by
## 40 4 4 300 5 inanimate the
## 41 4 4 270 6 inanimate crane
## 42 4 4 284 7 inanimate were
## 43 4 4 300 8 inanimate deposited
## 44 4 4 300 9 inanimate on
## 45 4 4 299 10 inanimate the
## 46 4 4 329 11 inanimate roof.
## 47 5 5 255 NA animate <NA>
## 48 5 5 285 1 animate The
## 49 5 5 330 2 animate student
## 50 5 5 331 3 animate graded
## 51 5 5 328 4 animate by
## 52 5 5 315 5 animate the
## 53 5 5 284 6 animate professor
## 54 5 5 300 7 animate received
## 55 5 5 286 8 animate a
## 56 5 5 314 9 animate low
## 57 5 5 284 10 animate mark.
## 58 6 6 300 NA inanimate <NA>
## 59 6 6 299 1 inanimate The
## 60 6 6 285 2 inanimate recipe
## 61 6 6 315 3 inanimate selected
## 62 6 6 299 4 inanimate by
## 63 6 6 315 5 inanimate the
## 64 6 6 285 6 inanimate judges
## 65 6 6 314 7 inanimate did
## 66 6 6 270 8 inanimate not
## 67 6 6 300 9 inanimate deserve
## 68 6 6 285 10 inanimate to
## 69 6 6 315 11 inanimate win.
## 70 7 7 285 NA animate <NA>
## 71 7 7 270 1 animate The
## 72 7 7 300 2 animate specialist
## 73 7 7 285 3 animate requested
## 74 7 7 284 4 animate by
## 75 7 7 270 5 animate the
## 76 7 7 284 6 animate hospital
## 77 7 7 300 7 animate finnaly
## 78 7 7 330 8 animate arrived.
## 79 8 8 300 NA inanimate <NA>
## 80 8 8 285 1 inanimate The
## 81 8 8 300 2 inanimate jewelry
## 82 8 8 314 3 inanimate identified
## 83 8 8 286 4 inanimate by
## 84 8 8 284 5 inanimate the
## 85 8 8 285 6 inanimate victim
## 86 8 8 300 7 inanimate was
## 87 8 8 255 8 inanimate held
## 88 8 8 269 9 inanimate for
## 89 8 8 345 10 inanimate questioning
## 90 8 8 300 11 inanimate as
## 91 8 8 375 12 inanimate evidence.
We do the same for the comprehension data, but we also need to extract the correct answer and the response to the comprehension question.
comprehension_question2 <- comprehension_question %>%
select(trialNumber, itemID, rt, condition, sentence, comprehension_question, correctAnswer, correct, response)
print(comprehension_question2)
## trialNumber itemID rt condition
## 1 1 1 959 animate
## 2 2 2 554 inanimate
## 3 3 3 554 animate
## 4 4 4 569 inanimate
## 5 5 5 451 animate
## 6 6 6 345 inanimate
## 7 7 7 390 animate
## 8 8 8 405 inanimate
## sentence
## 1 The defendant examined by the lawyer turned out to be unreliable.
## 2 The gold transported by the guards was closely watched.
## 3 The teacher loved by the class was very easy to understand.
## 4 The bricks lifted by the crane were deposited on the roof.
## 5 The student graded by the professor received a low mark.
## 6 The recipe selected by the judges did not deserve to win.
## 7 The specialist requested by the hospital finnaly arrived.
## 8 The jewelry identified by the victim was held for questioning as evidence.
## comprehension_question correctAnswer correct response
## 1 Was the defendant reliable? FALSE FALSE f
## 2 Was the gold closely watched? TRUE TRUE f
## 3 Was the teacher hard to understand? FALSE FALSE f
## 4 Were the bricks deposited on the ground? FALSE FALSE f
## 5 Did the student receive a low mark? TRUE TRUE f
## 6 Did the recipe deserve to win? FALSE FALSE f
## 7 Did the specialist arrive? TRUE TRUE f
## 8 Was the jewelry held for questioning? TRUE TRUE f
Finally, we can perform some simple analysis on the data. For example, we can calculate the average reading time for each target regions (Regions 4 to 6).
sentence_reading2 %>%
filter(regionNumber %in% c(4,5,6)) %>%
group_by(regionNumber) %>%
group_by(condition,.add = T) %>%
summarise(mean_rt = mean(rt, na.rm = TRUE),
sd_rt = sd(rt, na.rm = TRUE),
n = n())
## `summarise()` has grouped output by 'regionNumber'. You can override using the
## `.groups` argument.
## # A tibble: 6 × 5
## # Groups: regionNumber [3]
## regionNumber condition mean_rt sd_rt n
## <int> <chr> <dbl> <dbl> <int>
## 1 4 animate 288 30.1 4
## 2 4 inanimate 274. 33.6 4
## 3 5 animate 270. 44.0 4
## 4 5 inanimate 277. 46.6 4
## 5 6 animate 265. 28.4 4
## 6 6 inanimate 266. 28.4 4
We can also calculate the accuracy of the comprehension questions.
comprehension_question2 %>%
summarise(mean_accuracy = mean(correct, na.rm = TRUE),
sd_accuracy = sd(correct, na.rm = TRUE),
n = n())
## mean_accuracy sd_accuracy n
## 1 0.5 0.5345225 8