vignettes/e-jspsych-integration.Rmd
e-jspsych-integration.Rmd
jsPsych is a powerful library for constructing behavioral experiments in Javascript. It is possible to embed jsPsych within psychTestR. This is useful when you want to take advantage of jsPsych’s timed stimulus presentation facilities.
This tutorial was written with reference to jsPsych 6.1.0. Unfortunately the jsPsych API is subject to change, which means that the code provided in this tutorial may need some editing to work with future versions of jsPsych. Please contact the package maintainer if you notice problems along these lines.
Normally we create a jsPsych test by writing an HTML file. Here is the ‘Hello World’ example from the jsPsych website:
<!DOCTYPE html>
<html>
<head>
<title>My experiment</title>
<script src="jspsych-6.1.0/jspsych.js"></script>
<script src="jspsych-6.1.0/plugins/jspsych-html-keyboard-response.js"></script>
<link href="jspsych-6.1.0/css/jspsych.css" rel="stylesheet" type="text/css"></link>
</head>
<body></body>
<script>
var hello_trial = {
type: 'html-keyboard-response',
stimulus: 'Hello world!'
}
.init({
jsPsychtimeline: [hello_trial]
})
</script>
</html>
We’re going to get this example running in psychTestR. The first step
is to download the jsPsych source code from the GitHub
repository, unzip the release file, and save the resulting directory
as a subdirectory of your current working directory, called for example
jspsych-6.1.0
.
To incorporate this code into psychTestR, we first create a file
called new-timeline.js
, where we define a function that
creates a jsPsych timeline.
function new_timeline() {
var hello_trial = {
type: 'html-keyboard-response',
stimulus: 'Hello world!'
;
}return [hello_trial];
}
We then make a second Javascript file, run-jspsych.js
,
containing the following boilerplate code:
function run_jspsych() {
.init({
jsPsychtimeline: new_timeline(),
display_element: 'js_psych',
on_finish: function() {
var json_data = jsPsych.data.get().json();
.onInputChange("jspsych_results", json_data);
Shinynext_page();
};
})
}run_jspsych();
Finally, we create an R file called my-test.R
, and
define a psychTestR page that wraps the jsPsych test. We do this using
helper functions from the htmltools
package, which allow us
to build HTML code programmatically from within R.
library(htmltools)
library(psychTestR)
jspsych_dir <- "jspsych-6.1.0"
head <- tags$head(
includeScript(file.path(jspsych_dir, "jspsych.js")),
includeScript(file.path(jspsych_dir, "plugins/jspsych-html-keyboard-response.js"))
)
ui <- tags$div(
head,
includeScript("new-timeline.js"),
includeScript("run-jspsych.js"),
tags$div(id = "js_psych")
)
hello_world <- page(
ui = ui,
label = "hello_world",
get_answer = function(input, ...) input$jspsych_results,
validate = function(answer, ...) nchar(answer) > 0L,
save_answer = TRUE
)
We can then run this as a full psychTestR test by adding the
following code to my-test.R
:
elts <- list(
one_button_page("You are about to take the 'Hello world' test."),
one_button_page("When you see 'Hello world', press SPACE to continue."),
hello_world,
elt_save_results_to_disk(complete = TRUE),
final_page("You finished the test.")
)
test <- make_test(
elts = elts,
opt = demo_options(
display = display_options(
full_screen = TRUE,
css = file.path(jspsych_dir, "css/jspsych.css"))
))
shiny::runApp(test)
Note that we’ve added two display options:
full_screen = TRUE
sets the test to display in
fullscreen, to reflect the default display configuration of
jsPsych.css = file.path(jspsych_dir, "css/jspsych.css")
tells
psychTestR to incorporate the default jsPsych style sheet. You can
provide multiple CSS files to this argument if you wish to incorporate
your own CSS styling.We can now inspect the test results by loading the generated RDS file
in output/results/
. You can do this by clicking on the file
in the RStudio viewer, or by using the readRDS
function.
Using the function as.list()
to coerce the results file to
a readable format, we can see that the jsPsych output has been saved as
a JSON string in the slot $results$hello_world
.
This proof of concept should extend naturally to more sophisticated
jsPsych tests. In particular, you will want to extend
new-timeline.js
to provide a timeline that describes your
desired experimental structure. You can also extend
run-jspsych.js
to incorporate various options that you
would normally pass to jsPsych.init()
, as well as passing
additional CSS files to display_options
. Good luck! Please
contact the package maintainer if you encounter any issues.