# Equal distribution of trials among conditions

**URL:** <https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335>\
**Category:** Coding\
**Tags:** randomization, counterbalancing\
**Created:** [December 4, 2021, 9:43pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335 "2021-12-04T21:43:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 4, 2021, 9:43pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/1 "2021-12-04T21:43:27Z")

</div>

Hi,

I have 5 conditions regarding the congruency between 3 different types of stimuli. When I run the experiment, the number of trials were not distributed to the conditions equally. Is there a way to do it?

 ![image](https://us1.discourse-cdn.com/flex002/uploads/psychopy/original/3X/3/6/368ca7efd56294f813ab5a0aae733b585f36d617.png)

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 4, 2021, 11:16pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/2 "2021-12-04T23:16:46Z")

</div>

The way I’ve most recently approached this issue is to set up a shuffled list of conditions for each type of stimulus and .pop() one from the appropriate list for each trial.

---

<div class="post-metadata">

**Author:** ![Becca](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/becca/32/34260_2.png) [@Becca](https://discourse.psychopy.org/u/Becca)\
**Post date:** [December 5, 2021, 4:14pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/4 "2021-12-05T16:14:34Z")

</div>

Hi There,

An easier way to do this might be to set this in the conditions trial spreadsheet you feed in - for example if I have 10 trials and I was 5 congruent and 5 incongruent - I would simply ensure that 5 rows in the conditions file corresponded to congruent and 5 corresponded to incongruent. Is there a reason that you prefer to manipulate this through code rather than from the spreadsheet?

Thanks!  
Becca

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 5, 2021, 9:19pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/6 "2021-12-05T21:19:57Z")

</div>

Try

```auto
conditionChoice1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
shuffle(conditionChoice1)
conditionChoice2 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
shuffle(conditionChoice2)
conditionChoice3 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
shuffle(conditionChoice3)

if stimType == 1:
     thisCondition = conditionChoice1.pop()
elif stimType == 2:
     thisCondition = conditionChoice2.pop()
elif stimType == 3:
     thisCondition = conditionChoice3.pop()

```

where stimType is a column in the spreadsheet

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 8:29am UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/8 "2021-12-06T08:29:18Z")

</div>

I suspect that you are re initialising the list every time. The setup and shuffle should be in Begin Experiment.

Please could you show the code you’re trying and confirm the total number of each cond\_number

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 11:43am UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/10 "2021-12-06T11:43:35Z")

</div>

That’s the error I expected you to get.

When you create the conditionChoice lists in Begin Experiment you need to make sure they have enough in them for all of your trials. If you have 127 trials divided by 3 values for cond then that’s about 42 values for each. You’ll need to go slightly over if you don’t have a multiple of 5.

However, in your code I note that you have cond = 4 and 5 as well. If cond is a column in your spreadsheet then you will have problems online if you try to alter it in your code.

Does cond 4/5 need a value for thisCondition or not?

It might be worth trying to call cond and thisCondition something more different. I’m confused about what two variables you are trying to randomise here.

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 12:29pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/12 "2021-12-06T12:29:53Z")

</div>

> [@B.D.5](#):
>
> Half of the trials are condition 2 (condnumber what you called stimtype)

If this is true then you need more than 30 items in conditionChoice2.

---

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 6, 2021, 12:46pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/13 "2021-12-06T12:46:37Z")

</div>

Yes I do not understand why this happens.

Can it be due to the fact that probablity of having condition 2 is somehow more than the others?

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 1:23pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/14 "2021-12-06T13:23:07Z")

</div>

How many times does condition 2 occurs in your 127 trials? If you can’t work that out, then you should step back and think about how your conditions are defined.

---

<div class="post-metadata">

**Author:** ![jtseng](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/jtseng/32/32082_2.png) [@jtseng](https://discourse.psychopy.org/u/jtseng)\
**Post date:** [December 6, 2021, 6:25pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/15 "2021-12-06T18:25:58Z")

</div>

This is a fun little exercise in probability. As I understand it, you have three categories of stimuli: images, words, and square. Congruency is defined by the matching index values between the three categories of stimuli. If this is right, then here’s one approach from my end:

**1. Generate and group into conditions all possible triplet combinations**  
Just as was noted in this post’s discussion, there’s an uneven amount of triplets per condition when you group together the triplets. To prevent an uneven distribution, you should explicitly sample from each condition group, as sampling independently from each _stimulus category_ (i.e., choose a random image, random word, and random square out of options 1-6) will likely return a triplet that falls under the all-incongruent condition. This is because, out of 216 possible combinations (because you have [6 options] to the power of [3 chosen]), 120 out of 216 triplets are all-incongruent.

So, how can we do this? Using two key elements:

- The handy `itertools` package’s [`product` function](https://docs.python.org/3/library/itertools.html#itertools.product)
- `Numpy`'s [`unique` function](https://numpy.org/doc/stable/reference/generated/numpy.unique.html), which you can use to analyze the occurrence of elements in the triplet (or any other array)

```python
from itertools import product
import numpy as np

# set up the options (1-6 images or words or imagery)
dataset = ['1', '2', '3', '4', '5', '6']

# initialize arrays to hold triplets per condition
cond1 = [] # all congruent
cond2 = [] # all incongruent
cond3 = [] # first two congruent (e.g., 1-1-2)
cond4 = [] # last two congruent (e.g., 1-2-2)
cond5 = [] # first and third congruent (e.g., 1-2-1)

# product(dataset, dataset, dataset) returns all triplets for vals 1-6
for triplet in product(dataset, dataset, dataset): 
    vals, inv = np.unique(triplet, return_inverse=True) 
    # vals = unique values found in the triplet, so 112 -> [1, 2]
    # inv = indices to reconstruct original array - useful for us to group
    
    if len(vals) == 1:
        # if there's only 1 unique value, it's congruent
        cond1.append(triplet)
    elif len(vals) == 3:
        # if there are 3 unique values, it's completely incongruent
        cond2.append(triplet)
    elif len(vals) == 2: # if there are two unique values... 
        if all(inv == [0, 0, 1]) or all(inv == [1, 1, 0]): # and repeated value starts at position 0 (XXY)
            cond3.append(triplet)
        elif all(inv == [0, 1, 1]) or all(inv == [1, 0, 0]): # and repeated value starts at position 1 (XYY)
            cond4.append(triplet)
        else: # repeated values at 1st and 3rd position
            cond5.append(triplet)

```

I encourage you to run this segment of code in Python, then print some variables to make sense of it:

- `print(cond1)` and swap `cond1` for other variables to inspect the triplets and make sure it’s what you expect
- `print([len(cond1), len(cond2), len(cond3), len(cond4), len(cond5)])` will return an array with how many triplets are in each category. Use this to understand why your previous approach wasn’t resulting in an even distribution.

**2. Creating an even distribution of conditions**  
Now, you can come up with a way to generate an array that will dictate which condition the triplet presented comes from. You’ll need to figure out a way to:

- Generate an array that has 125 elements with numbers 1-5 each appearing 25 times representing an even distribution of conditions: `[1, ..., 1, 2, ..., 2, 3, ...]`
- Shuffle it: `[1, 5, 4, 2, 2, 3, 5, ...]`
- Use the array to choose which condition group (i.e., `cond1`, `cond2`, etc.) to randomly sample from: `['444', '626', '311', '352', '512', ...]`
- Map each value onto the stimuli: `[(image4, word4, square4), (image6, word2, square6), ...]`

Hope that helps!

---

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 6, 2021, 6:49pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/16 "2021-12-06T18:49:15Z")

</div>

> [@jtseng](#):
>
> ```auto
> import numpy as np
> 
> ```

Thank you so much for your effort 🤗  
I guess it will take a while for me to understand this with my poor coding knowledge.

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 7:14pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/17 "2021-12-06T19:14:26Z")

</div>

It should be possible to set up the spreadsheet with balanced numbers of your different conditions rather than using a fully coded solution.

---

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 6, 2021, 8:56pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/18 "2021-12-06T20:56:11Z")

</div>

Since every word, image, imagery is randomly selected among 6 options it is not possible to define a color for a possible combination. The combination is demonstrated only after a loop iteration (thisWord\_color).

I do not know if there is a way to integrate possible combinations (attached) into the study excel sheet.

[colorperm.xlsx](https://discourse.psychopy.org/uploads/short-url/n8QgjBA5D7VInfOEs1R6Scedyet.xlsx) (20.6 KB)

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 6, 2021, 9:11pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/19 "2021-12-06T21:11:44Z")

</div>

It looks to me that you have 5 conditions

What I would do is have a list of your six colours and shuffle before each trial.

allincong = colour[0], colour[1], colour[2]  
allcong = colour[0], colour[0], colour[0]  
imagewordcong = colour[0], colour[0], colour[1]  
imageimagerycong = colour[0], colour[1], colour[0]  
wordimagerycong = colour[0], colour[1], colour[1]

Unless you care about the specific colours, they just need to be random.

---

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 7, 2021, 1:44pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/20 "2021-12-07T13:44:39Z")

</div>

is there a way to assign these colour[…] variables to the images or words that is gonna be presented?

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 7, 2021, 1:52pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/21 "2021-12-07T13:52:21Z")

</div>

imageCol = colour[0]  
wordCol = colour[1]  
imageryCol = colour[2]

Have a look at my crib sheet for how to set up colours as variables.

> **[PsychoPy Python to Javascript crib sheet 2021](https://docs.google.com/document/d/183xmwDgSbnJZHMGf3yWpieV9Bx8y7fOCm3QKkMOOXFQ/view#heading=h.8845j7egd9gd)**
>
> PsychoPy version 2021.1.3-2021.2.2Python to JavaScript Crib Sheet Compiled by Wakefield Morys-Carter, Oxford Brookes UniversityPlease share widely and follow Psych\_Stats on twitter. PsychoPy 2021 is a major update with several new features. When...

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 7, 2021, 2:26pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/23 "2021-12-07T14:26:58Z")

</div>

Yes, I just showed the principle, not all the variations. Please show the code you’ve tried.

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 7, 2021, 3:22pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/25 "2021-12-07T15:22:38Z")

</div>

You need if statements.

---

<div class="post-metadata">

**Author:** ![wakecarter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.psychopy.org/wakecarter/32/5753_2.png) [@wakecarter](https://discourse.psychopy.org/u/wakecarter)\
**Post date:** [December 7, 2021, 4:10pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/27 "2021-12-07T16:10:18Z")

</div>

Try a conditions file with just one column called condType and then:

```auto
if condType == 'allincong':
     thisImage_color = colour[0]
     thisWod_color = colour[1]
     thisImagery_color = colour[2]
elif condType == 'allcong'
     thisImage_color = colour[0]
     thisWod_color = colour[0]
     thisImagery_color = colour[0]
# You will need to add the rest yourself

```

---

<div class="post-metadata">

**Author:** ![B.D.5](https://avatars.discourse-cdn.com/v4/letter/b/e274bd/32.png) [@B.D.5](https://discourse.psychopy.org/u/B.D.5)\
**Post date:** [December 8, 2021, 2:57pm UTC](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335/28 "2021-12-08T14:57:09Z")

</div>

This didnt work either. Probably because there is no list called thisimage\_color. Etc but the images are read from thisImage list. The color is randomly selected. Eventhough your suggestion works it only labels the existing conditions

[Next page](https://discourse.psychopy.org/t/equal-distribution-of-trials-among-conditions/26335.md?page=2)
