Reply To: Choosing subet of items to present

PennController for IBEX Forums Support Choosing subet of items to present Reply To: Choosing subet of items to present

#6198
Jeremy
Keymaster

Hi Maria,

Since my last reply on this thread, I came up with another pretty useful function, pick, that I introduced on that thread. It makes it easier to randomize a set of trials and pick just a subset of it, and maybe even pick some more from the remaining trials later on if your design requires it (which your current design does require, if I understand correctly). You also no longer have to use GetTable().filter or define those number variables.

Your current design has one more requirement though, which is to retrieve the trials that you previously picked, and from that retrieval set, pick again a random subset of trials. So I will propose a new version of the pick function here, which will allow you to embed pick recursively (since you need to pick from a picked set). To be clear, you should use the code below, not the one from the linked thread—you can place it at the top of your main script for example:

function Pick(set,n) {
    assert(set instanceof Object, "First argument of pick cannot be a plain string" );
    n = Number(n);
    if (isNaN(n) || n<0) 
        n = 0;
    this.args = [set];
    this.runSet = null;
    set.remainingSet = null;
    this.run = arrays => {
        if (this.runSet!==null) return this.runSet;
        const newArray = [];
        if (set.remainingSet===null) {
            if (set.runSet instanceof Array) set.remainingSet = [...set.runSet];
            else set.remainingSet = arrays[0];
        }
        for (let i = 0; i < n && set.remainingSet.length; i++)
            newArray.push( set.remainingSet.shift() );
        this.runSet = [...newArray];
        return newArray;
    }
}
function pick(set, n) { return new Pick(set,n); }

Then you can use it like this, for example:

fillers = randomize("filler")
tests = randomize("test")

picked_fillers = pick(fillers, 4)
picked_tests = pick(tests, 3)

repeat_fillers = pick(randomize(picked_fillers), 2)
repeat_tests = pick(randomize(picked_tests), 2)

Sequence(
    picked_fillers/*4 trials*/, picked_tests/*3 trials*/,
    "break",
    repeat_fillers/*2 trials*/ , repeat_tests/*2 trials*/ , pick(fillers,1)/*1 trials*/ , pick(tests,2)/*2 trials*/
)

Some explanations:

  1. I first randomize all the trials labeled “filler” and all the trials labeled “test”, and I store the result in variables that I name fillers and tests, respectively
  2. Then I use pick on those variables, so as to pick the first four and the first three trials from those randomized sets, and store the picked trials in picked_fillers and picked_tests, respectively. After that, the sets stored in the variables fillers and tests have lost four and three trials, respectively
  3. Then I use pick on the (randomized) variables picked_fillers and picked_tests, and store the result in repeat_fillers and repeat_tests, respectively. You need to randomize here, because otherwise you would always pick the first trials from the sets in the picked_ variables, which would effectively result in systematically repeating the oldest (=first) trials from the first half of the experiment
  4. Finally, I build my Sequence using those variables, and also use pick one last time on fillers and tests again which, at that point, no longer contain the trials that were transferred to picked_fillers and picked_tests in the meantime, so we’re sure that by doing so, we’re not repeating trials that were already presented in the first half

If you need further randomization, you can use rshuffle (e.g. rshufflle(repeat_fillers,repeat_tests,pick(fillers,1),pick(tests,2))) or randomize, but keep in mind that the latter only accepts single arguments, so you would need to also use seq in this case: randomize( seq(repeat_fillers,repeat_tests,pick(fillers,1),pick(tests,2)) )

Let me know if you have questions

Jeremy