Pseudoranomization

PennController for IBEX Forums Support Pseudoranomization

This topic contains 7 replies, has 2 voices, and was last updated by Jeremy Jeremy 2 weeks, 1 day ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #6495
    Avatar
    gdemeurisse
    Participant

    Hi Jeremy,

    I’m working on pseudorandomization for my experiment, and I’ve seen your responses both on this PCIbex support forum and the Ibex support forum. I tried plugging those lines of code into my own script, but I can’t get it to work. I think I’m not understanding the following line of code — randomizeNoMoreThan(anyOf(“1A”, “1B”, “1C”, “2A”, “2B”, “2C”),2), — and how I should implement it into my script given how I’ve coded my conditions in my .csv file.

    The .csv file (just a practice file) I uploaded has four conditions: ambiguous-incongruent, ambiguous-congruent, unambiguous-incongruent, unambiguous-congruent. I have each four conditions balanced between three groups, group A, group B, and group C. So there are x numbers of all four conditions between each three groups.

    I have it all randomized, so there won’t be consecutive responses from group C, group C, or group B, group B, etc. In addition to randomizing the groups, I also want to pseudorandomize the conditions so that I don’t get, within group A, B, or C, two consecutive fillers, or two consecutive unambiguous-congruent conditions, so on and so forth.

    However, when I plug the .js script (and the randomizeNoMoreThan(anyOf(“1A”, “1B”, “1C”, “2A”, “2B”, “2C”),2),.) I still get two consecutive fillers, or two consecutive of the other critical conditions.

    This is my script, minus the actual template and trials beyond the sequence.

    function RandomizeNoMoreThan(predicate,n) {
        this.args = [predicate];
        this.run = function(arrays) {
            let moreThanN = true;
            let order;
            while (moreThanN){
                order = randomize(predicate).run(arrays);
                moreThanN = false;
                let previousType = "";
                let current_n = 0;
                for (let i = 0; i < order.length; i++){
                    let currentType = order[i][0].type;
                    if (currentType != previousType){
                        current_n = 1;
                        previousType = currentType;
                    }
                    else{
                        current_n++;
                        if (current_n > n){
                            moreThanN = true;
                            break;
                        }
                    }
                }
            }
            return order;
        };
    }          
    function randomizeNoMoreThan(predicate, n) {
        return new RandomizeNoMoreThan(predicate,n);
    }
    
    Sequence("gettheid", "Intro", randomizeNoMoreThan(anyOf("1A", "1B", "1C", "2A", "2B", "2C"),2), "exit", randomize("experiment"), SendResults() , "bye");
    

    I think what I’m most confused about is how I can randomize my conditions when they’re coded like “concon” (for congruent-congruent), but it’s my groups that are coded as A, B, or C. So, it would seem that with the script above, I’d pseudorandomize the groups, and not the conditions.

    I’m not sure if that makes sense — I can try and clarify if need be.

    Thank you in advance!

    Grace

    #6497
    Jeremy
    Jeremy
    Keymaster

    Hi Grace,

    First, I want to make sure that we’re using Group the same way: in PCIbex, you can name a column either Group or List and the effect will be that, for any given participant, they will only see trials generated from the table that have a given value in that column. As you can see in the tutorial here for example, some participants will only see trials generated from the A rows, and the other participants will only see trials generated from the B rows. I think that, in your case, you are defining groups within participants, and you are not referring to that notion of group, is that correct?

    If I understand you correctly, your trials are characterized by three factors: i. A vs B vs C, ii. ambiguous vs unambiguous, iii. congruent vs incongruent. However, you seem to only use the first factor to label your trials. I can’t make sense of the number before A/B/C, does it correspond to the trial’s index?

    The way randomizeNoMoreThan works, you pass a set of trials as its first argument (eg. using anyOf, like in your code) and you pass a number N as a second argument. It will make sure that the output series of trials contains at most N consecutive trials that share the exact same label. So in your case, it makes sure that you don’t have more than 2 consecutive trials labeled 1A, that you don’t have more than 2 consecutive trials labeled 1B, etc. So if you want to use randomizeNoMoreThan as it is, my guess is you’ll need to revise how you label your trials.

    I understand you don’t want two consecutive trials with the exact same crossing of the two last factors (ambiguity and congurency) but I’m not sure how exactly the group factor interacts with them, so I’m not sure how you want the trials resulting from further crossing the two factors with group to be presented to each participant. If you could clarify that to me, we could work on a better adapted version of the randomizeNoMoreThan function

    Jeremy

    #6501
    Avatar
    gdemeurisse
    Participant

    Hi Jeremy,

    Thank you!

    My group column is similar to what is in the tutorial. So I have a column for group, and each row with the corresponding conditions is assigned to either group A, group B, or group C. I tried to copy and paste and align a part of the table in my .csv file here in the textbox; hopefully it stays all lined up once I post this. (None of the stimuli presented like the sentences, fillers, etc are what will actually be in the live experiment.)

    If I’m understanding this correctly, the randomizeNoMoreThan with 1A, 1B, 1C etc is just a label of trials, and isn’t about the pseudorandomizing specifically of the group column, where the groups are A, B, C? In my trial type, “con” is for congruent, and “inc” is for incongruent. Ideally, we’ll have some filler sentences and some filler questions, so “Q” means question (but I’ve omitted the question column for space).

    The “group” column seems to be randomized already with the randomize(“experiment”) code, so what I want is to find a way to pseudorandomize my “trialtype” column, so the UA_con etc labels. At one point I tried randomizeNoMoreThan(anyOf(“UA_con”, “UA_inc”, “AM_con”),2) (so on and so forth with the rest of the trials) but I didn’t think that was right, because I didn’t think I was supposed to edit your randomizeNoMoreThan(anyOf script.

    Group 	trial_ID. trialtype	        Stim	                             Flanker	Response	
    A		   UA_con	Put the dumplings in the pot	              <<<<<	    F		
    A		   UA_inc	Pour the coffee in the mug	              <<><<	    J		
    A		   AM_con	Put the dumplings in the pot in the pan	      >>>>>	    F		
    A		   AM_inc	Pour the coffee in the mug down the drain     >><>>	    J		
    A		  AM_con_Q	Sit in the chair in the living room 	      <<<<<	    F		
    A		  UA_con_Q	    Sleep on the bed	                      >>>>>	    F		
    A		    con		                                              >>>>>			
    A		    inc		                                              <<><<			
    A		   filler	This is a filler sentence 		                    F		
    B		  UA_con	Put the dumplings in the pot	              <<><<	    J		
    B		  UA_inc	Pour the coffee in the mug	              >>>>>	    F		
    B		  AM_con	Put the dumplings in the pot in the pan	       >><>>	    J		
    B		   AM_inc	Pour the coffee in the mug down the drain.    <<<<<	    F		
    B		  AM_con_Q	Sit in the chair in the living room 	       >>>>>	    F	 
    B		  UA_con_Q	      Sleep on the bed	                       >>>>>		
    B		    con		                                               <<><<			
    B		    inc		                                               <<<<<	    F		
    B		  filler	  This is a filler sentence 		

    Thank you again!

    Grace

    #6502
    Avatar
    gdemeurisse
    Participant

    For clarification purposes, since the table didn’t line up right, “trial_ID” should be blank, and the column label “stim” lines up with the sentences (basically stim = sentences).

    #6505
    Jeremy
    Jeremy
    Keymaster

    I think there is a misunderstanding about the identity and interactions of the different elements in PCIbex.

    Tables and columns are never randomized: tables are static pieces of data, typically in the form of CSV files, used to generate trials using the Template command.

    What ends up randomized are the trials themselves in the running order, on the basis of their labels. You define the running order using the Sequence command and by referring to trial labels inside it, optionally filtering the correspondingly-labeled trials using various functions like the pre-built function randomize, or the custom function randomizeNoMoreThan in this case.

    For example, using the table from your message, this bit of code would make sure you don’t have more than two consecutive trials labeled con nor more than two consecutive trials labeled inc (I had to extract those labels from your trialtype column, since each of the values it contains are already unique within each group):

    Sequence( randomizeNoMoreThan(anyOf("con","inc"),2) )
    
    Template( row =>
      // keep only 'inc' or 'con' as the label
      newTrial( row.trialtype.replace(/^.*(inc|con).*$/,"$1") ,
        newText(row.Flanker).center().print(),
        newTimer(100).start().wait(),
        getText(row.Flanker).remove()
        ,
        newText(row.Stim).center().print(),
        newKey("FJ").log().wait()
      )
      .log( "type"     , row.trialtype )
      .log( "group"    , row.Group )
      .log( "flanker"  , row.Flanker )
      .log( "sentence" , row.Stim )
      .log( "CorrectResponse" , row.Response )
    )

    To be clear, whenever you run the experiment, you will only see 8 trials, either all from the rows where Group is A, or all from the rows where Group is B. Three of those 8 trials are labeled “inc” and the other five are labeled “con,” based on trialtype. The trial generated from the row where trialtype is “filler” will not be run because its label is neither “inc” nor “con” (and because we used anyOf("con","inc"))

    If you only want to prevent more than two consecutive trials generated from rows with the exact same value in trialstype then your table already gives you that because, as I said earlier, each value in that column is unique within its Group. If you want to prevent series of three-or-more trials generated from rows whose trialstype value contains the same AM/UA prefix and/or the same inc/con affix, then we’ll need to modify the randomizeNoMoreThan function, because right now it only tests for exact matches between trials’ labels

    Hopefully my message made some points clearer, but please ask any questions you still have

    Jeremy

    #6507
    Avatar
    gdemeurisse
    Participant

    Hi Jeremy,

    Thank you so much! I just incorporated that into my script, and I think it worked, but I’m going to break it into smaller chunks and go through it a few times to make sure.

    If I run into any more questions and can’t find an answer on previous posts then I’ll post back here.

    Thank you again for your help!

    Grace

    #6510
    Avatar
    gdemeurisse
    Participant

    Hi Jeremy,

    I’ve run into some problems with randomization now. Back in October, I uploaded a table with the three groups (like I mentioned above in my first posts), groups A, B, and C. I was able to get it to randomize the group presentation with randomize(“experiment”), and it only ever presented stimuli from group A, B, or C; never all three. In my results file, I could see that the participant received group B’s stimuli, group A’s, stimuli, etc. That .csv file was entitled StimuliTemplate2.csv.

    I’ve since created some new tables (like the one that I’m using to figure out pseudorandomization) and they are more or less the same as StimuliTemplate2. However, when I’m using these tables, all groups end up getting presented in the experiment. So all stimuli from groups A, B, and C get presented. Really the table “StimuliTemplate2.csv” is the only one where stimuli is presented from only one group, despite the fact that I’m using nearly the exact same script (at some points I’ve cut out the practice trials and gone right to the experiment, but otherwise the script remains the same). I’ve revised the newer tables multiple times: I’ve added information into the “trial_ID” column so that all columns are filled out, and I’ve added rows into each group so there is an even and equal number of stimuli in each group (i.e eight congruent flankers in group A, eight in group B, etc). Nothing I try seems to fix the problem.

    Do you have any idea what might be causing these issues?

    Thank you!

    Grace

    #6511
    Jeremy
    Jeremy
    Keymaster

    Hi Grace,

    The Group column is automatically detected by PCIbex. The reasons I can see why it would fail to do so are either because the table has another column overriding it (eg. a column named List) or because your column’s name is not exactly Group. Make sure you don’t have an extra-character somewhere like a dot or a space character in the name of your column

    Jeremy

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.