7. Data logging and handling
We already mentioned several times how to log your data in NeuroTask Scripting. The basic function for this is log(), which adds a row of new data to the data table in your account. For most experiments this type of storage is sufficient In other words, data logging is easy and the form controls such as input(), check(), and scale() log the subject’s responses automatically. This chapter describes the rest of the data management system, including a few cases where you need more options to store and perhaps retrieve data.
As an example of why you would want to store and retrieve some data, consider the case that you invite a certain group of patients to take a test battery that consists of three fairly long tests (say 12 min each). Some patients may get interrupted and then later return to the test battery. In such a case, it would be handy if you could somehow retrieve which parts of the test battery that had already taken, so that you could skip these when they return. For these and several other use cases, NeuroTask Scripting has functions that let you not only log but also update and retrieve data in a running script.
In this chapter, we will first discuss the log() function. Then, we will tell a few things about where your data ends up, some tricks to get a better view on your data, and how to download it. Finally, we will discuss how you could store and retrieve data for more complicated situations.
7.1 Data logging with log()
The log() function is the basis of all data logging. NeuroTask Scripting distinguishes between data logging and storing: Data logging never overwrites existing data and always adds a new row to your data table. Data storing, however, will overwrite the data row in your table if it has the same label. We will discuss data storing towards the end of this chapter.
To log some data, you can simply write:
log(42,"var3");
This will add a row of data to the data table in your account with name ‘var3’. It will also include a timestamp with the exact date and time when the data was logged. And it will have information about the subject, invitation, and session.
In most case, you will first collect a response from a participant in a variable and then log its value:
1 var e, b;
2
3 b = addblock().text("Get ready to click with the (left) mouse button...");
4 await(4000);
5 b.clear();
6
7 await(randint(1000,3000);
8 b.text("Now");
9 e = b.await("click");
10
11 log(e.RT,"Reaction Time");
12 await(5000);
This script is a simple reaction time task. First, a text appears on the screen with the text ‘Get ready to click with the (left) mouse button…’. After 4 s the text disappears and after a random interval of 1 to 3 s the text ‘Now’ appears. We use the randint(min,max) function which generates a random integer in the range min to (but not including) max. The click event is caught by the await() function its return value capture in variable e. As explained in the chapter on events, the return value already contains a property RT that holds the reaction time, which we log as shown.
For reaction times, we would normally like to run several trials and then average these. This can be done with a for loop. Let’s run ten trials and adjust the script accordingly:
1 var e, b;
2 var e, b, i;
3
4 b = addblock().text("Get ready to click with the (left) mouse button...");
5 b = addblock();
6
7 for (i = 0; i < 10; ++i)
8 {
9 b.text("Get ready to click with the (left) mouse button...");
10 await(2000);
11 b.clear();
12
13 await(randint(1000,3000);
14 b.text("Now");
15 e = b.await("click");
16
17 log(e.RT,"Reaction Time");
18 await(1500);
19 }
20
21 await(5000);
This script has a for loop that runs ten times. We have moved creating of the block outside the loop, because we don’t want to create it ten times; we just want to show the instruction text ten times. We have also add a 1.5 s wait at the end of the loop so that after clicking the participant gets a brief pause. We shortened the time the instruction is shown to 2 s, because 4 s felt quite long if you run several trials.
Script 7.2 will log ‘Reaction Time’ ten times, each time with different values, which will show up as rows in your data table. Once you have download the table (discussed below) you could analyze the reaction times, for example, in Excel. To facilitate this and to give the participant some feedback, let’s keep track of the total time in a variable named total, calculate the average reaction time and assign to variable average, log this variable, and use it to give some feedback to the participant.
1 var e, b, i;
2 var e, b, i, total, average;
3
4 total = 0;
5 b = addblock();
6
7 for (i = 0; i < 10; ++i)
8 {
9 b.text("Get ready to click with the (left) mouse button...");
10 await(2000);
11 b.clear();
12
13 await(randint(1000,3000);
14 b.text("Now");
15 e = b.await("click");
16
17 log(e.RT,"Reaction Time");
18 total += e.RT
19 await(1500);
20 }
21
22 average = total/10;
23
24 log(average,"Average RT");
25 b.text("You average reaction time was: " + average + " ms");
26 await(5000);
This script is starting to become a real reaction time experiment. Now, let’s look at how the data appears in the data table of your account. But first we need to go over one more thing: Even without your logging, a NeuroTask script always logs certain data automatically.
7.2 Data that is always logged in ‘activated’ scripts
When a participant starts a new session by clicking the ‘Start’ button (which you may have given another label), the NeuroTask Scripting system records the beginning of a session and also collects certain data about the browser, whether high-precision timing is available, and the size of the screen. At the end of the session the time is recorded as well. A full list of automatically recorded data is as follows:
| Name | Value |
|---|---|
| nt_session_state | started |
| nt_ip_address | 213.93.228.65 |
| nt_browser_with_version | Chrome 41 |
| nt_browser_type | Chrome |
| nt_operating_system | Windows |
| nt_screen_height | 1080 |
| nt_screen_width | 1920 |
| nt_window_height | 640 |
| nt_window_width | 1280 |
| nt_precision | high |
| nt_RAF | general |
| nt_now | general |
| nt_session_state | finished |
All variable names have the ‘nt_’ prefix. As we will explain in the next section, this makes it easy to single them out in the data tables of your account, or to suppress them.
The ip address, given with ‘nt_ip_address’ variable, is the web address of the computer network on which the participant was taking the experiment. It is always collected by an internet server and may help to identify returning participants, in particular ‘banned’ subjects, which you identified in previous experiments. It is generally not possible to obtain the name or identify from an ip address (at least not without a court order), though there are fairly reliable methods of linking an ip address to a country or area within a country. An ip address, however, is not completely reliable to identify returning subjects, because sometimes many people share one ip address and some internet providers reassign ip addresses unpredictably. It is also possible to deliberately hide your ip address by using special services and browsers, in which case even the country where the participant is doing the experiment may be wrong: you can for example be using a French ip address even if you are actually in the United States.
The remaining data can give some insight into the quality of the data collected. Knowing the browser and operating system may be important to monitor whether participants were working on an outdated browser or an atypical operating system. In some case, this may lead to exclusion from the experiment. The variable ‘nt_now’ indicates whether the high resolution timer now() is available and nt_RAF says something about whether precise onset timing of visual stimuli is possible.1 Both of these variables are summarized in the ‘nt_precision’ variable. If it says ‘high’, timing is likely to be in the millisecond precision range. If it says ‘low’, timing may be up to 16 ms or more off, which may or may not be a problem.
Screen and window size are important indicators of the visual resolution, but they say nothing about the physical size of the participant’s screen. It is impossible to find out the physical dimensions, short of asking participants to somehow measure their own screen. They do, however, help to recognize whether they were working on very low resolution screens or wet her they did the experiment in a small window of a large screen, and therefore may have been distracted.
The ‘nt_session_state’ here says ‘started’ and then ‘finished’, which may not seem very informative, but bear in mind that there is also a column with date/time, not shown here, at which each variable was recorded. With this you can easily estimate the total length of a session. A very short or very long session may indicate strange behavior, such as giving brief nonsense answers (or always choosing the first option) or use of external sources and notes.
The ‘nt_session_state’ variable can take on two other values, namely ‘blurred’ and ‘focused’. A ‘blur’ occurs when the participant moves away from your experiment by clicking on another window. When the participant returns, a ‘focus’ event occurs. Frequent ‘blurs’ may cause problems. It may, for example, indicate that a participant is checking Facebook or email, while in the middle of a reaction time experiment.
Together, the automatically collected ‘nt_’ variables give valuable information about the reliability of the collected data and the diligence of your participants.
7.3 Data tables in your account
All data collected ends up in the NeuroTask Scripting database, which resides with the Strato corporation’s servers in Germany. The Strato servers are iso 27001 certified. They are protected with very high security standards and are subject to the German and European laws on privacy and government access. Your own logged data is accessed in the data tables. An convenient way to inspect your data is to look up your script in the Scripts listing table and click on the
table icon. In the figure below you can see the data for two subjects who took the sleep survey.
If you are reading this on a fairly large screen or print-out, you may be able to read the name and value of variables that were logged. The ‘Created’ column tells you to the second when the variable was logged. Other columns, from left to right are, ‘Index’, ‘Type’, ‘ID’, ‘Script’, ‘Invite’, and ‘Subject’. ‘Index’ is a number that uniquely identifies the row of data in the entire NeuroTask database. ‘Type’ and ‘ID’ will be discussed below. ‘Script’ is the id number of the script that generate the data. ‘Invite’ is the invitation sent through NeuroTask Scripting by email to invite subjects to take the experiment. If the subject took the experiment through the general URL, this value is 0. If it is not, you can click the number, which links to the original Invite. There, you will be able to see the invite details, like which other subjects where invited and when this occurred. ‘Subject’, finally, contains the ID number of the subject who did the experiment. If the subject used the general script URL or if you invited the subject with an anonymous Invite, a new (anonymous) will have been generated by the NeuroTask Scripting system. If not, that is, if you invited the subject personally through a non-anonymous Invite, the number will be that of the known subject who did the experiment. You can also click on the subject number, which is linked to the subject’s record.
In this particular data table, you can see that the survey was taken by two subjects with numbers 727 and 734. Both are anonymous, which you can find out by clicking on them: their labels will read ‘anon727’ and ‘anon734’, which is the default labeling system for anonymous subjects. The ‘anonymity’ is not shown in the table to prevent adding yet one more column, and it is rarely the case that you have a mix of anonymous and known subjects; most experiments are either anonymous (e.g., via a general URL) or by invitation only (e.g., patients or friends and family).
What a ‘session’ is
We did not yet discuss the ‘Type’ and ‘ID’ columns. ‘Type’ refers to the level at which you are logging data. By default, you are logging data at the ‘session’ level: one ‘subject’ W, invited by ‘invite’ X, doing an experiment programmed by ‘script’ Y written by ‘author’ (i.e., user) Z. The same subject, may use his or her invite link again to take the experiment for the second time. The ‘subject’, ‘invite’, ‘script’, and ‘author’ will be the same but the ‘session’ will now be different: Once an experiment has been completed the session is closed.
What if a session has not been closed? If a subject stops doing an experiment midway, the experiment ‘session’ is not closed. If the subjects continues after a while, data is added to the same session. This is the meaning of ‘session’ you see in the ‘Type’ column. One subject can participate in several consecutive sessions: after completing the experiment, he may sometimes decide to do it again (e.g., to get a better score). After starting the experiment for the second time, a completely new session will be opened with a new session ID in the data tables.
A session is recognized by the NeuroTask Scripting system only if the subject continues on the same computer, using the same internet browser. The reason is that the NeuroTask Scripting system leaves so called session cookies behind and these are located in the browser’s database on a specific computer.
When does the system decide the session has to be closed, even though the subject has not finished it? We have set this period at 48 hours, meaning that a subject has two days to get back to the experiment to finish it. After that, an entirely new session is started. So, if a subject starts an experiment on Monday, is interrupted and only gets back to it on Friday (by clicking the experiment URL again), the old session will be closed and the experiment will be treated as a new experiment session.
What ‘Type’ means in the data table
One could say that ‘session’ is the most basic level at which you can log data in the sense that each logged row of data also contains information about the script (and thus author), invite, and subject. Sometimes, however, you want to log data at a ‘higher’ level. For example, for a particular subject you want to log which experiments he or she did. This can be accomplished by setting the third argument of the log() function to ‘subject’, like this
log("Corsi Block Task","Experiment","subject");
If you include a line of code like this in all experiments, e.g.,
log("Tower of London Task","Experiment","subject");
and perhaps many more in other scripts, each of these would be logged as usual, except that the type is now ‘subject’ and the ‘ID’ column now contains the ID of the subject. This is only useful if the ID of the subject is known, which is only the case with a non-anonymous invite. In all other case, new ‘anon’ IDs will be generated.
It is also possible to log data at the level of the ‘invite’. Suppose, you invite 10 anonymous subjects and you want to keep track of their reaction times. You could add a line of code:
log(average,"average","invite");
where average is as in the Script 7.3 above. If you had sent different invites to different groups of people, this would be a way to get a quick overview of their performance.
Another useful level is the ‘script’. This keeps track of all sessions by all invites and subjects that have been done for a given script. You may suspect there is a time-of-day effect and therefore log the overall performance of each experiment at the level of the ‘script’:
log(total_performance,"Performance","script");
Now, all experiments done will leave one row of data in the table that has type ‘script’ (and the ID of this particular script, e.g., 4201).
We can go one level higher, where we will reach you, the ‘author’. If you log data the ‘author’ type, you can accrue data across several scripts. Suppose, you have several similar scripts with a comparable general performance measure (e.g., reaction time) and you wish to track time-of-day effects on these, then you could simply include a line:
log(total_performance,"Performance","author");
In theory you could go one level higher, ‘global’, which all authors could log and view. This level is currently not available but may be in the future, if we see a good reason for it.
Most of the examples in this section are somewhat contrived, the sense that if you would have written:
log(total_performance,"Performance"); // 'session' is the default type
it would have been recorded just fine. And each data row would have included the script ID anyway (and invite and subject IDs if available). The real power of the different levels becomes apparent with data storage and retrieval, where you can increase and decrease numeric values and update data values, which can later be retrieved. This can make your scripts much more ‘intelligent’ and responsive.
7.4 The main data type selector
If you store data that is not of type ‘session’, you will not immediately see these if you arrived at the page via clicking on the table icon. By default, only the ‘session’ data is shown for a specific script.
If you want to see other types of data, you can select this in the Type drop-down menu all the way on top. If you for example select ‘Subject’, the page then gives you an option to select in the ‘Show only for…’ drop-down. If you would select ‘Script’ here, you are then given the opportunity to select a specific script in the dropdown select list labeled ‘… with ID or name’. For example, you could select script ‘1343: MyExperiment’. The whole selection should be read as: ‘Give me all Subject data for Script 1343: MyExperiment.’
In this way quite a few variations can be made, all which can be downloaded to Excel, as is described below. It is not currently possible, however, to get a mix of say ‘Subject’ and ‘Session’ data in one table. You will have to construct this yourself out of several downloaded tables.
7.5 Data storage and retrieval
Suppose, your experiment consists of two parts, say a memory task followed by a sleep survey. A subject does the memory task but then needs to do something else and turns off her computer. Later that day she remembers she still need to finish the survey part, turns her computer back on and surfs back to your experiment. To her great annoyance she has to do the memory task again and she decides not to bother with the experiment anymore. How can you prevent this situation?
Above, when discussing ‘session’, we said that a session remains open for 48 hours, giving a subject to return to it within two days (even an anonymous subject). But how do you know whether a subject has already completed a section of your experiment? For this, we use store() and retrieve(), as follows:
1 var bookmark;
2
3 bookmark = retrieve("Where");
4
5 if (bookmark !== "Part 1 Completed")
6 {
7 // Here comes the memory task
8
9 store("Part 1 Completed","Where");
10 }
11
12 // Here comes the sleep survey
The retrieve() function will return undefined if the variable does not (yet) exist, which will be the case when a subject first starts this experiment. After completing the memory task, the variable ‘Where’ will have the value ‘Part 1 Completed’. This means that the first part of the experiment will now be skipped. You can also use this technique to prevent subjects from doing an experiment twice, though in our experience it is better to allow this and simply not analyze this additional data.
As a second argument of retrieve, you could also have specified ‘subject’. The ‘Where’ variable would have been stored at the subject level. For invited (non-anonymous) subjects, this has the advantage that they can in principle continue the experiment on a different computer and also after 48 hours. The default level is ‘session’. Other values are ‘invite’, ‘script’ and ‘author’ (i.e., you).
Let’s extend the technique above to more than two parts and use the ‘subject’ level instead of the ‘session’ level. We will use a number as a bookmark and increase it as the subject does more parts:
1 var bookmark = retrieve("Where","subject") || 0;
2
3 if (bookmark < 1)
4 {
5 text("Press '1'"); // dummy task
6 awaitkey('1');
7 store(1,"Where","subject");
8 }
9
10 if (bookmark < 2)
11 {
12 text("Press '2'"); // dummy task
13 awaitkey('2');
14 store(2,"Where","subject");
15 }
16
17 if (bookmark < 3)
18 {
19 text("Press '3'"); // dummy task
20 awaitkey('3');
21 store(3,"Where","subject");
22 }
23
24 text("Experiment completed!");
Here we use a well-known JavaScript idiom to assign a default value to a variable that may have value undefined (or null):
var bookmark = retrieve("Where","subject") || 0;
The ||-operator evaluates the expression from left to right. As soon as it encounters something that evaluates to true it returns that value, or else the last value evaluated. If retrieve() returns undefined2, as it will when the variable does not yet exist, the ||-operator will skip the first part and try the second part, which it then returns.
When a subject does this script for the first time, bookmark is 0 and the first part will be done. If the subject does task 1 (i.e., press 1) and then closes the webpage, the value of bookmark is stored as 1. On opening the experiment again, the usual Landing Page is shown, but now when subject presses the Start button, he or she skips the first part and is now asked to press 2.
If the subject completes the entire experiment and then returns to it later, he or she will start over from the beginning, as a second experimental session will be created with a new subject. The reason is that the system has no way of finding out whether the same person is doing the experiment again or a friend, relative or other person who has access to the same computer.
The retrieve() function also has a third argument, namely a timeout, which is set to 5000 ms by default. If the retrieve() function does not succeed in retrieving a value from the server within the timeout period, it will return null. You can disable timeout by setting the third argument to 0. But beware, in case the internet connection fails the script will stay stuck and not move forward.
If a variable does not exist for the level at which retrieve() is called, it will return undefined. So, if you do this: store(3,"Where","subject") and then x = retrieve("Where"), x will be undefined, because retrieve("Where") tries to retrieve (only) ‘session’ variables, whereas you stored ‘Where’ at the ‘subject’ level. But if you do x = retrieve("Where","subject"), x should equal 3.
You can check for null and undefined like this:
var x = retrieve("Where");
if (x === undefined)
{
// Variable is not yet stored
}
if (x === null)
{
// There was a timeout
}
Storing ‘behind the scenes’ or storing now
There is no timeout period for store() or log(), because these function do their job ‘behind the scenes’. While the rest of your script continues to run, the store() and log() functions are collecting data until they have enough or until no data has come in for a while. Then, they communicate with the server and send the data for processing and storage there. This does not interfere with your script.
With retrieve() this is not possible because the value must be retrieved before the script can usefully continue. Therefore, we let the script wait until the value has been secured or until timeout.
If you ever have a situation where you need to be certain for the good operation of your script that a value has been stored on the server, you can use the store_now() function, which works like store() but blocks further processing until the server has confirmed the correct storage of the variable.
increase() and decrease()
There may be cases where you want to keep count of something, for example, how often a certain experiment has been done. Or you may want to assign consecutive numbers to your subjects and use these for your own bookkeeping. For this purpose, we have included the increase() function, which like store_now() will wait for a confirmation and then return the increased value. You can use it like this:
var subject_id = increase("Subject ID","script");
If the variable ‘Subject ID’ does not yet exist, it will be inserted into the data table with starting value 0 plus your initial increase value, which is 1 by default. If it exists, the value of the variable will be increased. This only works with (signed) integers. You can increase with a greater step size, by specifying this as a third argument.
So, if this would be the very first time the script is run by any subject, subject_id would receive the value 1. On each subsequent run, the return value would be 1 higher. Also, the ‘Subject ID’ variable in your data table would reflect how many subjects have done your experiment.
The decrease() function works completely similar to increase(), except that the specified amount is decreased from the current value. Note that both increase() and decrease() have default timeout periods of 5000 ms, which can be adjusted by adding a fourth argument (e.g., 10000 for 10 s or 0 if you want no timeout at all, see comments above).
7.6 Working with the data tables
In this section, we will go over a few tricks for working with data tables. Note that these are not just used for session data, but also to present overviews of subjects, invites, and scripts. All of these can be downloaded to Excel and other formats and managed as described below. We will here focus on how to manage data collected in an experiment, but the principles are similar if you want to say manage the overview table in which all subjects are listed.
If you go to a script and then click on the table icon, you will see all data collected by that script during experimental sessions; each time log() was called another row was added to the table. If you have many subjects taking your tests and if you collect much data per script, this may result in thousands of rows. Fortunately, the data tables offer several ways to make inspection of your data more manageable, notably sorting and filtering.
Clicking on one of the headers (Type, ID, etc.) will sort the table according to that column. By default only 20 rows are shown, but in the Rows menu at the bottom, you can set this as high as 320. Next to the Rows menu, at the bottom of the table, is the Columns menu. There, you can uncheck the columns you are not interested in at the moment. These will be hidden from view and, if you wish, may be excluded from a download.
To alert you to any hidden rows and columns (lest you forget you had hidden these), at the very top of the table, the number of hidden rows and columns (if any) is given in the blue field above the column. If there are not hidden rows or columns, these fields turn grey.
Filtering data
Each column in the tables has a so called ‘filter’ option, which allow you to hide certain rows. Below the column header is a field that says ‘Type filter’ in pale grey letters, where you can type a ‘search’ text. You could, for example, type 'nt_' in the filter field of the ‘Name’ column. Any row of which the variable name contains 'nt_' somewhere (not necessarily at the beginning) will be shown and all other rows will be hidden. The number of rows hidden is shown in the blue field at the top-left of the table. The 'nt_' variables are the ones that are collected automatically. If you want to hide those rows, e.g., to focus on your own data, you must put an exclamation mark at the beginning, which in many computer languages, including JavaScript, means opposite or negation. So, you would enter '!nt_' in the filter field. By planning ahead a little with the names you give to your variables, you could make good use of these filter options. For example, you could filter on 'cond1' or 'cond2', or have summary variables like 'summary_test1', 'summary_test2', where you could filter on 'summary_' to get a quick overview.
For advanced users, there is even the possibility to use regular expressions as filters, if you start a filter text with a question mark it is interpreted as a regular expression. Regular expressions are quite powerful but hard to learn and their usage here is beyond the scope of this introductory manual. As an example: ‘?e$’ would show all names ending in ‘e’. And '?nt_|rt_' would show all values that contain either 'nt_' or 'rt_' (or both).
In the a date column, such as the Created column, you can filter among others by ‘days ago’. Today’s data can be shown with '0..1' (two dots). Last week’s data, including today, with '-7..1' and so on. Decimals are allowed to if you want say the last few hours. You can also click on the > < symbols, which will present you with calenders where you can select the ‘from’ and ‘to’ dates you wish to inspect.
In numeric fields, such as the Script (ID) column, you can use ranges as well, such as 1000..1200. Or !1000..1200 to exclude this range. Just typing say 1023 will show only the data of the script with ID 1023.
Finally there is the checkbox filter, which has values ‘indeterminate’ (which is the default, meaning it is not active), ‘checked’ where only the checked rows are shown, and ‘unchecked’ where only the unchecked rows are shown.
All of these filters not only change your view of the table by hiding certain rows, the view achieved by them can also be exported, if you want that.
7.7 Exporting data
If you scroll all the way down below the table, you see a title bar that says ‘Excel or CSV Export’. Clicking on brings up an image like this:
In the File Format menu on the left you can select the type of file you want to download:3
- Excel 2007
- Excel 5
- CSV (plain text with comma-separated values)
- HTML (web page)
With the Selection menu you specify which ‘view’ of the table you wish to download:
- All
- Filtered
- Checked
‘All’ gives you all rows. Filtered gives you only the visible rows and columns. This is handy if you want to download a specific portion of your data. Checked will export only the columns that you checked by clicking the checkboxes on the very left-hand side. This is useful for very specific selections of rows.
The Separators menu is relevant if you want to export your data for use in a translated (non USA English) version of Excel, such as Dutch, which uses the comma for a decimal sign and the point to separate thousands.
In the menus at the bottom of the data table, you can also find three Quick Export options. These do not run via the NeuroTask server, but work locally, in the browser. They only produce Excel and the formatting is somewhat atypical. You can use it as a fallback in case there is a problem with the regular exporting facility, such as a sudden internet connectivity problem.
Pivot tables, or how to make your tables ‘square’ again
Some users may wonder about our choice to store all data in a big table with many rows and few columns. Wouldn’t it be handier to have a square table with say the subjects as rows and their data as columns. With thought very hard about this and our conclusion was: No, this is not handier except in certain specific case. The format we use is the least limiting format, because of one extremely handy tool: pivot tables. These are present in all Excel programs and we strongly encourage you to spend one or two hours familiarizing yourself with them.
A pivot table turns a long table like you download from NeuroTask Scripting into an arbitrary square table with summary statistics such as ‘count’, ‘mean’, and ‘standard deviation’. You can format an Excel pivot table in minutes, using dragging and dropping of fields. For example, suppose you have this:
| x | y |
|---|---|
| 1 | 2 |
| 1 | 4 |
| 2 | 3 |
| 2 | 6 |
x could be subjects IDs and y a percentage correct on certain trials or reaction times.
With a pivot table we can take the mean value over all repeated measurements in conditions 1 and 2, which would give us this:
| x | mean |
|---|---|
| 1 | 3 |
| 2 | 4.5 |
What an Excel pivot cannot do is to turn the long table into a square with textual and other values; you are forced to use numeric values and summary statistics as values of the pivot table (but not of the row and column headers).
7.8 Logging, storing, and the ‘response’ object
Data which is collected with the log() or store() functions is always also available in the response object. So, if in your script you write:
log(391,"average_rt");
The value 391 can be accesses in the response object, e.g.,
var save_for_later = response['average_rt'];
More useful is the fact that each string in NeuroTask Scripting has a format() function, which can take the response object as an argument, such that its key-value pairs can be used in a string, as follows:
var s = "Your reaction time was {average_rt} ms".format(response);
Now string s will be equal to ‘Your reaction time was 391 ms”. As is explained in the chapter on form controls, each of these controls already does this by default, so that earlier responses can be used in the labels and explanatory text of these controls.
- RAF is an abbreviation of ‘requestAnimationFrame’, this is a signal that the next screen is about to be generated by the computer, which typically happens exactly 60 times per second. See the advanced manual for a more in-depth discussion of this.↩
- Many values in JavaScript are considered
false, e.g.,undefined,null, 0, and the empty string"". We advise not to rely on this except with well-known usage cases, like this.↩ - SPSS output is not supported at the moment, but will be in the future, as will be other formats if there is a demand for it.↩