Skip to content

if

Experiments Surveys & forms

if holds one or more conditions evaluated against the participant’s last response after the trial completes. When a condition is true, the trial jumps to the destination in the paired then column instead of advancing sequentially. Use it for branching, screening, repeat-until-correct loops, and performance gates.

An if without a then on the same row never runs.

Put one condition in the cell, and the place the participant should go to in the paired then cell of the same row. When the trial ends, the condition is checked against the last response; if it is true, the experiment jumps to that destination instead of continuing to the next row.

Several conditions can share one row. Separate them with ; and give then the same number of ;-separated destinations: condition 1 goes with destination 1, condition 2 with destination 2, and so on. The first condition that is true wins.

Within a single condition, & means AND and | means OR, so correct & RT<600 is true only when both hold.

The forms a single condition can take are listed under Options. They are tried in the order shown there, and the first form that fits decides how the condition is read.

FormExampleMeaning
responseCode= prefixresponseCode=1,2True when the response codes recorded for the trial are exactly those, in any order. List several with ,
responseCode!= prefixresponseCode!=1,2True when they are not those. List several with ,; a ; would split the cell into separate conditions instead
stimX referencestim2True when the clicked or selected position corresponds to that stimulus, even when the stimulus positions were shuffled
correctcorrectLast trial scored correct
incorrectincorrectLast trial scored incorrect
has(x) / !has(x)has(yes)True when the response contains (or does not contain) that text; with the responseCode prefix it tests the response codes instead
%var% variables%correct.sum[2_0]%>=10, %rt-2%<500, %response[lab1]%==1The variable is replaced by its recorded value and compared as a number; the rest of the condition is taken exactly as written
old-style variables (no %)response[-1]==1The same replacement in the older spelling. Always use ==; a single = breaks the experiment when it starts
participant details%age%>=18Compares against a stored participant detail. Available keys: id, age, gender, sex_assigned_at_birth, education, handedness, sexual orientation, ethnicity, nationality, participant_other1_label..participant_other5_label
bare [label]response[lab1]Reads the value recorded on the row carrying that label
!value!3True when the response is not that value. Only numeric values negate correctly
<= >= < >RT<500Numeric comparison. It compares the reaction time when the condition mentions RT, the response codes when it mentions responseCode, and otherwise the response
range A_B1_5, RT100_500True when the value falls between the two bounds, inclusive. Not read as a range when the condition contains x, which is reserved for grid positions
plain value (fallback)yes, aTrue when the response is exactly that value
unreadable???A condition that cannot be read at all is always true

Variable syntax accepted inside %...%: base response|responseCode|rt|correct|%custom_var%, optional relative index (%response-2%), optional aggregate .avg|.mean|.sum|.max|.min|.modal|.perc|.count, optional bracket index [N], [a,b,c], [from_to], or [label] — the bracket index goes after the aggregate (%correct.perc[2_0]%; %correct[2_0].perc% is not recognised). Indexes of 0 or less are relative to the most recent value ([0] is the last one, [-1] the one before it), positive indexes are trial-file row numbers (header row = 1, so first trial = [2]), _ makes an inclusive range, , picks individual values, and a label resolves to that labeled row’s value.

Leave the cell empty on every row that should simply carry on to the next trial. The column can be left out of the file entirely if no trial branches.

  • Cell empty but then filled in: the first then destination is taken every time, with nothing to check.
  • Cell filled in but then left empty: nothing happens, because the conditions are never checked.
  • More conditions than then destinations: the extra conditions have nowhere to go, so when one of them matches the participant simply continues with the next trial.
  • then: conditions and destinations pair up in order. See the then page for what a destination can be.
  • key: key scoring uses the same condition grammar, so anything you learn here also applies to writing scoring rules.
  • label: %response[mylabel]% reads the response recorded on a labeled row, and then destinations can be labels instead of row numbers.
  • Break trials: a break row’s conditions are checked when the break ends.
  • Setup screens: consent, calibration and participant-details screens never branch. A condition only takes effect after a regular trial; test and form trials branch normally.

Repeat a practice block until 80% accuracy (row numbers include the header row):

typestimFormatstim1keyifthenlabel
practice.pngdog1practice_start
practice.pngcat2%correct.perc[-1_0]%>=80;%correct.perc[-1_0]%<804;practice_start
test.pngbird1

([-1_0] = the last two responses, i.e. this practice block; 4 = the trial-file row of the first test trial.)

Branch on the response with a fallback destination (the extra then acts as else):

typetrialTextkeyboardifthenlabel
testDo you smoke? (y/n)y nysmoker_q;main_start
testHow many per day?0 1 2 3smoker_q
testx.pngmain_start

Fast-and-correct gate combining AND:

typestimFormatstim1keyifthen
test.pngtarget1correct & RT<600+2
  • ! negation only works on numbers: !yes does not test the text yes, it tests “not 0”.
  • There are no parentheses: in a mixed condition every & binds tighter than every |, not left to right.
  • A condition that cannot be read at all is always true, but an unreadable part inside an & or | combination is worse: the experiment fails to start rather than failing quietly.
  • Aggregates need a bracket index: a bare %correct.perc% or %correct.sum% is never filled in, so the condition is silently false. Always write an index or a range, for example %correct.perc[2_0]%, %correct.perc[-9_0]%, or a labeled range.
  • Which value gets compared is decided by the text of the condition, case-sensitively. Any condition containing uppercase RT compares the reaction time, which can surprise you if a response value itself contains “RT”; lowercase rt<500 compares the response instead.

if appears in these worked recipes:

  • Skip on response: Ask one question and jump participants who answer yes straight past the practice block.
  • Accuracy-gated progression: Let participants advance to the test block only once their practice accuracy clears a threshold.
  • Branching questionnaire: Route participants to different questionnaire pages depending on their answer to an earlier question.
  • Screener then branch: Ask one eligibility question up front and end the session for participants who do not qualify.