psychopy.org | Reference | Downloads | Github

Getting the median of an array in javascript

Description of the problem: Hi, I am trying to store RT in an array to later get the median of that array as the next stimulus duration.

Here’s how I store the RT in an array:

var repro1_array = new Array (6);
var reproduction1;
var i = 0;
function iteration1RoutineEachFrame(trials) {
  return function () {
    //------Loop for each frame of Routine 'iteration1'-------
    let continueRoutine = true; // until we're told otherwise
    // get current time
    t = iteration1Clock.getTime();
    frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
    // update/draw components on each frame
    if ((_key_resp_allKeys.length === 2)) {
        key_resp.keys = _key_resp_allKeys.slice((- 1))[0].name;
        reproduction1 = (_key_resp_allKeys.slice((- 1))[0].rt - _key_resp_allKeys.slice((- 2))[0].rt);
        repro1_array[i] = reproduction1;
        i = i+1;
        continueRoutine = false;
    }
    
    if (polygon.status === PsychoJS.Status.STARTED && t >= frameRemains) {
          polygon.tStop = t;  // (not accounting for frame time here)
          polygon.frameNStop = frameN;  // exact frame index
        }
    

And here is how I get the median and define it as the next stimulus duration (seed 2):

var stimulus1;
var seed2;
function iteration1RoutineEnd(trials) {
  return function () {
    //------Ending Routine 'iteration1'-------
    for (const thisComponent of iteration1Components) {
      if (typeof thisComponent.setAutoDraw === 'function') {
        thisComponent.setAutoDraw(false);
      }
    }
    sum_ite1 += reproduction1;
    ite1_count += 1;
    const arr1Sort = repro1_array.sort();
    const len = repro1_array.length;
    const mid = Math.ceil(len/2);
    const median1 = 
        len % 2 == 0 ? (arr1Sort[mid] + arrSort[mid -1]/2 : arrSort[mid -1]);
    stimulus1 = (polygon.tStop - polygon.tStart);
    ite1_loop.addData("stimulus1", stimulus1);
    ite1_loop.addData("reproduction1", reproduction1);
    ite1_loop.addData("sum_ite1", sum_ite1);
    
    if ((ite1_count === trialNum)) {
        seed2 = (median1);
        ite1_count = 0;
        sum_ite1 = 0;
    }
    

As I try to run the experiment I get this error: Uncaught SyntaxError: Unexpected token ‘:’ for the line len % 2 == 0 ? (arr1Sort[mid] + arrSort[mid -1]/2 : arrSort[mid -1]);

I found this code online so I’m not sure whether it works the same way in Pavlovia. As I understood the colon operator was used to say “if mod is not 0 then take the mid value of the array”. But it didn’t work the same way here apparently. Could you help me understand why?

You’ve got a couple syntax errors. Typos in variable names and incorrect () grouping.

I find the playcode site useful for fixing javascript. Here’s your code fixed with a demo median calculation. It’s got a live editor and console so you can change things and see what happens.
https://playcode.io/626291

But beware that code isn’t bulletproof. Javascript does funny things. Like defaulting to sorting arrays alphabetically.

Corrected syntax.
//Changed sort to be numeric ascending
const arr1Sort = repro1_array.sort((a,b)=>a -b);

//Fixed typo and ()
const median1 =
len % 2 == 0 ? (arr1Sort[mid] + arr1Sort[mid -1])/2 : arr1Sort[mid -1];

2 Likes

Thank you very much! I was looking for a good web IDE like this. I’ll definitely use it.
And thanks for your corrections, they indeed solved it. :slight_smile:

@ales Hi Ales. I’ve got a few problems, I was wondering if you or anyone else can help.

So I changed how I determine the duration of the next stimulus from calculating the average of the previous trials to taking the median of the previous trials by using the code provided by @ales above.

However, I noticed a seemingly systematic error while doing that. When the code calculates the median, there is a significant increase in the difference between the actual stimulus duration presented on the screen (which should be the median) and what I want to present (which is again, the median). More specifically, when the calculated median is below < 500 ms, the stimulus duration that is calculated by frameN*frameDur is much higher (~1000 ms higher). And this definitely does not happen when I’m calculating the average as the next stim dur.

I couldn’t figure out where in the code this problem lies exactly. So here I am sharing the URL of my experiment: https://gitlab.pavlovia.org/pinartoptas/timingpriors_avg

I would appreciate any help.

Thanks in advance!