Multi-Category IAT on Minno?

80 views
Skip to first unread message

Jordan Axt

unread,
Sep 23, 2022, 12:00:18 PM9/23/22
to Minno.js
Hello Minno Group,

Are there any existing resources for running a Multi-Category IAT (MC-IAT) using minno? The MC-IAT is essentially a series of Brief IATs that uses multiple groups and then pairs those BIATs together so that participants complete each contrast. For example, an MC-IAT with four groups (Black, White, Asian, Hispanic) would be comprised of six BIATs (a Black-White BIAT, a Black-Asian BIAT, a Black-Hispanic BIAT, a White-Asian BIAT, a White-Hispanic BIAT, Asian-Hispanic BIAT). 

If no extensions or prior versions exist, do you have any advice on how to best adapt the BIAT extension for this purpose?

Thanks,
Jordan

--
Jordan Axt

Yoav Bar-Anan

unread,
Sep 23, 2022, 1:21:18 PM9/23/22
to Jordan Axt, Minno.js
Hi Jordan, 

You can check whether the MC-IAT in Nicole Lofaro's study provides what you need:

Yoav

--
You received this message because you are subscribed to the Google Groups "Minno.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to minnojs+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/minnojs/CAN9p%3DamXrMq%3DkuqMr%2BbeHe2Zsuxq19PTOrhJZZT23FOwuMn33w%40mail.gmail.com.

Jordan Axt

unread,
Sep 23, 2022, 3:45:56 PM9/23/22
to Yoav Bar-Anan, Minno.js
Hi Yoav,

Great, thank you. This is exactly what I was looking for.

Jordan
--
Jordan Axt

Jordan Axt

unread,
Oct 17, 2022, 10:52:32 AM10/17/22
to Yoav Bar-Anan, Minno.js
Hello Minno Group,

I am having trouble adapting the shared MC-IAT materials from 3-categories to 4-categories. This means the task would have to move from 8 blocks to 14 blocks. 

See below for a study that has a working MC-IAT, where the mciat.js file lists four categories, but only runs for eight blocks. Please let me know if there are any changes to either the mciat.js or mciatextension.js files that would extend the task for all 14 blocks (two practice blocks, and then the 12 blocks making up each combination of the four groups). Thank you!


Jordan

--
Jordan Axt

Yoav Bar-Anan

unread,
Oct 17, 2022, 11:44:02 AM10/17/22
to Jordan Axt, Minno.js
  Hi Jordan, 

I think that the relevant code is mostly in the mciatextension.js script. Specifically, the following code:
	    //These are the 6 orders of the first two blocks
	    //All the other blocks are determined by these two.
	    var blockSeqs4 = [
	        {f1:1, n1:2, f2:3},
            {f1:1, n1:3, f2:2},
            {f1:2, n1:1, f2:3},
            {f1:2, n1:3, f2:1},
            {f1:3, n1:1, f2:2},
            {f1:3, n1:2, f2:1}
        ];
...
function getBlockSequence(inID)
        {
            var blockSeq = [];
            var seq = blockSeqs4[inID-1];
            //All the blocks are derived from the first two blocks.
           blockSeq.push({focalCat:seq.f1, nonFocalCat:seq.n1});//Block 2

            blockSeq.push({focalCat:seq.f1, nonFocalCat:seq.n1});//Block 3 (1st critical)
            blockSeq.push({focalCat:seq.f2, nonFocalCat:seq.f1});//Block 4 (2nd critical)
            blockSeq.push({focalCat:seq.n1, nonFocalCat:seq.f1});//Block 5 (3rd critical = opposite of 1st)
           
            blockSeq.push({focalCat:seq.f2, nonFocalCat:seq.n1});//Block 5 (4th critical = two last focals)
            blockSeq.push({focalCat:seq.f1, nonFocalCat:seq.f2});//Block 6 (5th critical = opposite of 2nd)
            blockSeq.push({focalCat:seq.n1, nonFocalCat:seq.f2});//Block 7 (6th critical = opposite of 4th)

            return (blockSeq);
        }
...
//Set the category order: the sequence of focal categories.
		//The constraint is that each category appears as focal only 
		//after all the others appeared (exhausted)
		var blockSequence;
		if (piCurrent.blockSequenceID>0)
		{//select the block sequence from a list of all the sequences.
		    blockSequence = getBlockSequence(piCurrent.blockSequenceID);
		}
		else if (piCurrent.blockSequence)
		{
		    blockSequence = piCurrent.blockSequence;
		}

In mciat.js, the following line is relevant:
blockSequenceID : Math.round(Math.random() * 5),

This is what I think is going on in that code: 
1 The parameter blockSequenceID is set to a number between 1 to 5 (this might be due to a coding mistake because I think that it should have been between 1 to 6, so perhaps the code should have been Math.round(Math.random() * 6)].
2 The extension uses the value of blockSequenceID to determine which of the six possible orders to use, as defined in the variable blockSeqs4. 
2a Each of the six orders is defined by the first focal category (f1), the first non-focal category (n1) and the second focal category (f2). 
2b As shown in the getBlockSequence function, those details are all that the code needs in order to determine which category would be the focal category and which would be the non-focal category in each of the blocks of the task. 
2c If I understand the code of that function correctly, after the practice block, the same focal and non-focal categories appear in two consecutive blocks, which probably means that Block 2 is also considered a practice block. Only afterwards, all six contrasts appear, one block after the other. 

So, if you want four categories, I guess you need one general practice block, and then 4*3 contrast blocks, with the first one appearing twice at the beginning, once as a practice block and once as the first critical block. I am guessing that's why you wrote that it would require 14 blocks.
I recommend first to change the code to define 14 blocks, without thinking about the randomization. For example, in the getBlockSequence function:
 blockSeq.push({focalCat:1, nonFocalCat:2});//Block 2
            blockSeq.push({focalCat:1, nonFocalCat:2});//Block 3 (1st critical)
            blockSeq.push({focalCat:3, nonFocalCat:1});
            blockSeq.push({focalCat:4, nonFocalCat:2});           
            blockSeq.push({focalCat:2, nonFocalCat:3});
            blockSeq.push({focalCat:1, nonFocalCat:4});
            blockSeq.push({focalCat:4, nonFocalCat:3});
//Opposites
            blockSeq.push({focalCat:2, nonFocalCat:1});
            blockSeq.push({focalCat:1, nonFocalCat:3});
            blockSeq.push({focalCat:1, nonFocalCat:4});           
            blockSeq.push({focalCat:3, nonFocalCat:2});
            blockSeq.push({focalCat:4, nonFocalCat:1});
            blockSeq.push({focalCat:3, nonFocalCat:4});
Then, run to make sure that it shows you 14 blocks with four categories. That would mean that we probably understand correctly how the code works.
Next, you can think about how you want to randomize the order and what the rules you want to use in order to build the block sequence. Use those rules to change the code such that it would be relevant for 4 rather than 3 categories.
*There is probably also a way to support a variable number of categories, but it would require some more thinking.
I hope that helps, but let me know if you need more information.
Yoav

Jordan Axt

unread,
Oct 17, 2022, 12:41:43 PM10/17/22
to Yoav Bar-Anan, Minno.js
Hi Yoav,

Great, thank you for the quick help. Yes, you are understanding the task correctly in terms of the practice + critical block structure. Here is the showfiles link again:

Your code worked (save for one typo that repeated a specific pairing). The following does create all of the necessary pairings. 

           blockSeq.push({focalCat:1, nonFocalCat:2});//Block 2
            blockSeq.push({focalCat:1, nonFocalCat:2});//Block 3 (1st critical)
            blockSeq.push({focalCat:3, nonFocalCat:1});
            blockSeq.push({focalCat:4, nonFocalCat:2});          
            blockSeq.push({focalCat:2, nonFocalCat:3});
            blockSeq.push({focalCat:1, nonFocalCat:4});
            blockSeq.push({focalCat:4, nonFocalCat:3});
//Opposites
            blockSeq.push({focalCat:2, nonFocalCat:1});
            blockSeq.push({focalCat:1, nonFocalCat:3});
            blockSeq.push({focalCat:2, nonFocalCat:4});        
            blockSeq.push({focalCat:3, nonFocalCat:2});
            blockSeq.push({focalCat:4, nonFocalCat:1});
            blockSeq.push({focalCat:3, nonFocalCat:4});


This is still assigning to a fixed order, though. I tried the following in terms of creating a block sequence, but it does not appear to be working

     var blockSeqs4 = [
       {f1:1, n1:2, f2:3, n2:4},
       {f1:1, n1:2, f2:4, n2:3},
       {f1:1, n1:3, f2:2, n2:4},
       {f1:1, n1:3, f2:4, n2:2},
       {f1:1, n1:4, f2:2, n2:3},
       {f1:1, n1:4, f2:3, n2:2},
       {f1:2, n1:1, f2:3, n2:4},
       {f1:2, n1:1, f2:4, n2:3},
       {f1:2, n1:3, f2:1, n2:4},
       {f1:2, n1:3, f2:4, n2:1},
       {f1:2, n1:4, f2:1, n2:3},
       {f1:2, n1:4, f2:3, n2:1},
       {f1:3, n1:1, f2:2, n2:4},
       {f1:3, n1:1, f2:4, n2:2},
       {f1:3, n1:2, f2:1, n2:4},
       {f1:3, n1:2, f2:4, n2:1},
       {f1:3, n1:4, f2:1, n2:2},
       {f1:3, n1:4, f2:2, n2:1},
       {f1:4, n1:1, f2:2, n2:3},
       {f1:4, n1:1, f2:3, n2:2},
       {f1:4, n1:2, f2:1, n2:3},
       {f1:4, n1:2, f2:3, n2:1},
       {f1:4, n1:3, f2:1, n2:2},
       {f1:4, n1:3, f2:2, n2:1}        
       ];


When we first ran these studies on the old system, there was a constraint such that each focal category could only come up once for Blocks 2-6, 7-10, and 11-14 (e.g., White man was the focal category once in Blocks 2-6, once in Blocks 7-10, once in Blocks 11-14). It would be great to recreate that, but I would also be happy with just a fully randomized order. 

Thanks,
Jordan
--
Jordan Axt

Yoav Bar-Anan

unread,
Oct 17, 2022, 1:55:41 PM10/17/22
to Jordan Axt, Minno.js
Hi Jordan, 

The blockseq array is supposed to hold all the possible orders (so, it had 6 cells in the 3-category version), and each cell in that array is all the information needed to generate one of the six sequences, based on the algorithm defined in the getBlockSequence function. 
That code was designed to serve requirements I no longer remember clearly. For example, it allowed for the users of this extension to set the blockSequenceID (rather than select it randomly), which is supposed to be one of the six orders. 
If this is not a requirement in the present case, then you can delete any mention of blockSeqs4 and blockSequenceID from the code, and  program an algorithm for randomly setting the block sequence within each session, always using the getBlockSequence function.

For example, here is something I wrote but did not test:
  function getBlockSequence()
        {
            var blockSeq = [];
   //We will shuffle the four categories into the cats array. That is the randomization of the order.
            var cats = API.shuffle([1,2,3,4]);

  // The first block is practice and will be repeated in the following block.
           blockSeq.push({focalCat:cats[0], nonFocalCat:cats[1]});//Block 2

   //The pattern of the order is always the same: [0,1],[2,0],[3,1],[1,2], [0,3],[3,2],[1,0],[3,2], [0,2],[3,0],[2,3],[1,3].
   //But, these numbers of the cells in the cats array, so the actual numbers are randomly chosen each time this extension is executed.
            blockSeq.push({focalCat:cats[0], nonFocalCat:cats[1]});//Block 3 (1st critical)
            blockSeq.push({focalCat:cats[2], nonFocalCat:cats[0]});
            blockSeq.push({focalCat:cats[3], nonFocalCat:cats[1]});
            blockSeq.push({focalCat:cats[1], nonFocalCat:cats[2]});

            blockSeq.push({focalCat:cats[0], nonFocalCat:cats[3]});
            blockSeq.push({focalCat:cats[3], nonFocalCat:cats[2]});

            blockSeq.push({focalCat:cats[1], nonFocalCat:cats[0]});
            blockSeq.push({focalCat:cats[2], nonFocalCat:cats[1]});

            blockSeq.push({focalCat:cats[0], nonFocalCat:cats[2]});
            blockSeq.push({focalCat:cats[3], nonFocalCat:cats[0]});
            blockSeq.push({focalCat:cats[2], nonFocalCat:cats[3]});
            blockSeq.push({focalCat:cats[1], nonFocalCat:cats[3]});

            return (blockSeq);
        }

If that doesn't help, I will program+test, but it might take me a couple of days before I can get to this.

Yoav

Jordan Axt

unread,
Oct 17, 2022, 3:40:00 PM10/17/22
to Yoav Bar-Anan, Minno.js
Hi Yoav,

Yes, this works great. Your code randomizes the order. Thanks for the quick help here.

Best,
Jordan
--
Jordan Axt

Jordan Axt

unread,
Oct 19, 2022, 8:31:47 PM10/19/22
to Yoav Bar-Anan, Minno.js
Hi Yoav (and others),

I'm back with what I hope is my last question about the MC-IAT. Nicole's study doesn't have a debriefing page, and I am looking to create a page that has feedback for a pool study. It looks like there is something about feedback in the mciatextension file (e.g., fb_strongAssociationForCatWithAtt1):

But I am unsure on how to display the feedback in a debriefing. On the old system, the feedback was actually presented visually, since the four category scores are all relative to one another, with a vertical line that had the most positively evaluated categories near the top and the most negatively evaluated categories near the bottom.

If something like that is possible to make in minno, great. But if not, just giving feedback on the aggregate groups would also do the job (e.g., "Your data showed a strong positive association towards White men", "Your data showed a moderate positive association towards White women").

Thanks,
Jordan 


--
Jordan Axt

Yoav Bar-Anan

unread,
Oct 20, 2022, 1:11:16 PM10/20/22
to Jordan Axt, Minno.js
Hi Jordan,

* Notice that in your study, you are using a debriefing.js questionnaire, but you define it as a message task in the manager:
debriefing: [{
            type:'message', templateUrl: 'debriefing.js', piTemplate:'debrief', 
            name:'debriefing'
        }],
In this study, I defined it as a questionnaire:
 debriefing: [{
            type:'quest', scriptUrl: 'debriefing.js', 
            name:'debriefing'
        }]
* And, in your debriefing.js, the code tries to get the "feedback" property of a task named "iat", which does not exist in your study:
         '<p><%= global.iat.feedback %></p></div>' +
 
But, the truth is that fixing those would not be enough because global.mciat.feedback would only show a comparison between category 1 and category 2.

So, I created a quick fix in this study, by modifying the extension code a bit (so, you will need to copy that file into your own mciat extension).
I also slightly modified the debriefing.js file, by replacing the line shown above with:
		'<p><%= global.mciat.mciatScoreObj.allFBs %></p></div>' + 
Currently, the debriefing shows this:
image.png
You might want to get rid of the "Your data suggest" by adding fb_ arguments to your mciat.js script with your preferred text, and by editing the text in the debriefing page.

However, if one of the comparisons would have too many errors, too many fast trials, or not enough trials for computing a score, the error message would just appear in the list of feedback messages (e.g., the second feedback message would 'There were too many errors made to determine a result.'). That would seem odd in between the other feedback messages. If that would be the remaining problem, it can probably be handled by removing such error messages whenever there are other non-error messages, and I can add some code to implement that solution.

If you have an old debriefing file that showed the feedback visually, you can send it, and I'll see whether it is easy to adapt the code to Minno's debriefing.

Yoav


 


Jordan Axt

unread,
Oct 20, 2022, 2:06:26 PM10/20/22
to Yoav Bar-Anan, Minno.js
Hi Yoav,

Yes, that works great! Thank you for the fast help. Here's the showfiles link again for anyone in the future looking to run a four-category MC-IAT:

Jordan
--
Jordan Axt
Reply all
Reply to author
Forward
0 new messages