Formula basics
Formulas are a special language used on Conjointly to perform tasks such as:
- Calculating revenue in the simulator,
- Weighting respondents,
- Piping, including in redirects.
The language is inspired by R. While knowledge of R is not required, those familiar with R will find it easy to use formulas on Conjointly. One key difference is a much more relaxed approach to data types. For example, 1 + "2"
is not allowed in R, but it is allowed on Conjointly and returns 3
.
There are only four datatypes in formulas:
- Numbers (e.g.
1
,2.5
,-3.14
), which are always treated as double-precision floating point numbers (“numeric” type in R). However, for comparisons, precision is limited to six decimal places. - Strings (e.g.
"hello"
,"world"
). All operations on them are case-insensitive. - Booleans (i.e.
TRUE
orFALSE
). - Undefined, which is a special value that is returned when a variable is not defined.
Algebraic functions
Algebraic functions perform basic mathematical operations. They always return a number.
Operation | Syntax | Example usage | Result |
---|---|---|---|
Addition | x+y | 20+15 | 35 |
Subtraction | x-y | 10-3 | 7 |
Multiplication | x*y | 7*3 | 21 |
Division | x/y | 10/2 | 5 |
Exponential | x^y | 4^2 | 16 |
Important notes:
- Just like in R, if the supplied value is a string, it is converted to a number. If the string cannot be converted to a number, the result is
0
. +
does not work as a concatenator.- If either argument is
undefined
, the result isundefined
. - All numbers are treated as double-precision floating point numbers (“numeric” type in R).
- If a vector of numbers is supplied, operation is done on the first element of the vector only.
Example usages of algebraic functions are provided below.
Situation | Formula | Result | Comment |
---|---|---|---|
The GET variable gender is male | GETvariable("gender") * 5 | 0 | because male is forced into 0 |
The GET variable gender was not recorded | GETvariable("gender") * 5 | 0 | because the empty string is forced into 0 |
The GET variable age is 20 | GETvariable("age") * 5 | 100 | because age is converted into the number 20 |
"3" + 5 | 8 | because 3 is forced into the number 3 | |
"male" + " bird" | 0 | because + does not work as a concatenator |
Rounding formulas
Rounding formulas are used to adjust numerical values to a desired precision:
Function | Description | Example usage | Result |
---|---|---|---|
round(number) | Returns the value of a number rounded to the nearest integer. | round(1.2345) | 1 (number) |
ceil(number) | Returns the smallest integer greater than or equal to a given number. | ceil(1.2345) | 2 (number) |
floor(number) | Returns the largest integer less than or equal to a given number. | floor(1.2345) | 1 (number) |
toFixed(number,fractionDigits) | Converts a number to a string, retaining the specified number of decimals indicated by the optional parameter fractionDigits , which must be an integer from 0 to 20. If fractionDigits is not given or is misspecified, it is assumed to be 0. | toFixed(1.2345,2) | 1.23 (string) |
Example usages are provided below.
Situation | Formula | Result | Comment |
---|---|---|---|
The GET variable gender is male | round(GETvariable("gender")) | 0 | because male is forced into 0 |
The GET variable age is 20.02323212424 | toFixed(GETvariable("age")) | 20 | because age is converted into the number 20.02323212424 |
The GET variable age is 20.02323212424 | toFixed(GETvariable("age"),40) | 20 | because fractionDigits is misspecified and therefore assumed to be 0 |
The GET variable age is 20.02323212424 | toFixed(GETvariable("age"),-1.33) | 20 | because fractionDigits is misspecified and therefore assumed to be 0 |
The GET variable freq is -23.31 | ceil(GETvariable("freq")) | -23 | because ceil rounds up |
Comparison operators
Comparison operators are used to compare two variables. Comparisons operators always return TRUE
or FALSE
.
Operation | Syntax | Example usage | Result |
---|---|---|---|
Equals | x==y | 5==10 | FALSE |
Not equals | x!=y | 10!=3 | TRUE |
Greater than | x>y | 5>19 | FALSE |
Equal to or greater than | x>=y | 4>=4 | TRUE |
Less than | x<y | 6<10 | TRUE |
Equal to or less than | x<=y | 5<=1 | FALSE |
Rules for comparing strings:
- For the
==
and!=
operators:- If one of the supplied values is a string, it is converted to a number. If the string cannot be converted to a number, it will be forced to
0
. - If both variables are strings, the comparison is done alphabetically. For example,
"a"=="b"
returnsFALSE
and"a"=="a"
returnsTRUE
. Comparison is case-sensitive.
- If one of the supplied values is a string, it is converted to a number. If the string cannot be converted to a number, it will be forced to
- For other operators, strings are converted to numbers. If a string cannot be converted to a number, it will be forced to
0
.
Important notes:
- If a vector of numbers is supplied, operation is done on the first element of the vector only.
- Precision of numbers is limited to six decimal places. It is achieved by checking if the absolute value of differences is greater than one millionth.
- Falsy values work as in JavaScript:
undefined
will be equated to0
, or"0"
, ir an empty string, orFALSE
(and vice versa).
Example usages of comparison operators are provided below.
Situation | Formula | Result | Comment |
---|---|---|---|
The GET variable gender is male | GETvariable("gender") < 5 | TRUE | because male is forced into 0 |
The GET variable gender was not recorded | GETvariable("gender") < 5 | TRUE | because the empty string is forced into 0 |
The GET variable gender was not recorded | GETvariable("gender") == 0 | TRUE | because the empty string is forced into 0 |
The GET variable gender was not recorded | GETvariable("gender") != 0 | FALSE | because the empty string is forced into 0 |
The GET variable age is 20 | GETvariable("age") < 5 | FALSE | because age is converted into the number 20 |
"3" < 5 | TRUE | because 3 is forced into the number 3 | |
"5" < 4 | FALSE | because 5 is forced into the number 5 | |
"5" == 5 | TRUE | because 5 is forced into the number 5 | |
"male" < " bird" | FALSE | because both strings are forced into the number 0 | |
"male" == "Male" | FALSE | because comparison is case-sensitive | |
"male" == "male" | TRUE | ||
"0" == "" | FALSE | because both values are strings and compared as such | |
0 == "" | TRUE | because the empty string is forced into 0 | |
1.0000001 == 1.0000002 | TRUE | because the absolute value of the difference is 0.0000001 < 0.000001 | |
1.0000001 == 1.0000005 | TRUE | because the absolute value of the difference is 0.0000004 < 0.000001 | |
1.0000001 == 1.0000012 | FALSE | because the absolute value of the difference is 0.0000011 > 0.000001 | |
"" == FALSE | TRUE | because both strings are forced into the number 0 | |
"" == FALSE | TRUE | because both strings are forced into the number 0 |
Boolean operators
Boolean operators are used to combine or exclude comparison operations. Boolean operators always return TRUE
or FALSE
.
Operation | Syntax | Example usage | Result |
---|---|---|---|
Not | !x | !(10==5) | TRUE |
And | x&y | TRUE&(10==5) | FALSE |
Or | x|y | (10<4)|(10>2) | TRUE |
Important notes:
- If a vector of numbers is supplied, operation is done on the first element of the vector only.
- If either argument is not boolean (i.e. a number or a string), it is converted to boolean under the same rules as
x!=0
.
Example usages of boolean operators are provided below.
Situation | Formula | Result | Comment |
---|---|---|---|
!0 | TRUE | because 0!=0 is FALSE | |
!1 | FALSE | because 1!=0 is TRUE | |
!-1 | FALSE | because -1!=0 is TRUE | |
!"" | TRUE | because ""!=0 is FALSE | |
1|0 | TRUE | ||
9&7 | TRUE | because 9!=0 is TRUE and 7!=0 is TRUE | |
!-0.00000001 | TRUE | because -0.00000001!=0 is FALSE | |
!-0.001 | FALSE | because -0.001!=0 is TRUE | |
The GET variable gender is male | GETvariable("gender") & 5 | FALSE | because male is forced into 0 |
The GET variable gender was not recorded | GETvariable(“gender”) | 5 | TRUE | the empty string is forced into 0 , but 5!=0 is TRUE |
The GET variable gender was not recorded | GETvariable(“gender”) | 0 | FALSE | because the empty string is forced into 0 |
The GET variable gender was not recorded | GETvariable("gender") & 0 | FALSE | because the empty string is forced into 0 |
The GET variable age is 20 | !GETvariable("age") | FALSE | because age is converted into the number 20 , and 20!=0 is TRUE |
if and ifs functions
These functions return values depending on whether a condition is true or not:
if('condition', 'then', ['else'])
checks condition and returns a value if it isTRUE
or a different value if it isFALSE
.ifs('condition1', 'then1', ['condition2'], ['then2'], ..., ['else'])
returns a value that corresponds to the first TRUE condition, or the “else” value if all specified conditions areFALSE
.
Conditions can be specified using comparison operators. If a condition is not boolean (i.e. a number or a string), it is converted to boolean under the same rules as x!=0
.
If the “else” value is not specified, it is assumed to be undefined. If an undefined value is returned in a redirect formula, the redirect is not performed.
Example usages of if
are provided below:
Formula | Result | Comment | |
---|---|---|---|
if(3,3,5) | 3 (number) | because 3!=0 is TRUE | |
if(0,3,5) | 5 (number) | because 0!=0 is FALSE | |
if(FALSE,4,"male") | male (string) | ||
if(FALSE,4) | undefined | ||
if(TRUE,4,"male") | 4 (number) | ||
if(answer(234),4,"male") (but question 234 is not part of this experiment) | male (string) | because undefined!=0 is FALSE | |
if(wrongFormula(234),4,"male") | undefined | because the function wrongFormula does not exist |
Example usages of ifs
are provided below:
Formula | Result | Comment | |
---|---|---|---|
ifs(3,3,5,3,0) | 3 (number) | because 3!=0 is TRUE | |
ifs(0,3,5,4,-1) | 5 (number) | because 0!=0 is FALSE , but 5!=0 is TRUE | |
ifs(FALSE,4,TRUE,"male") | male (string) | ||
ifs(FALSE,4) | undefined | because the “else” condition is empty here | |
ifs(TRUE,4) | 4 (number) | ||
ifs(TRUE,4,"male") | 4 (number) | ||
ifs(answer(234),4,"male") (but question 234 is not part of this experiment) | undefined | because undefined!=0 is FALSE , but so is "male"!=0 and the “else” condition is empty here | |
ifs(wrongFormula(234),4,"male") | undefined | because the function wrongFormula does not exist |