Formula basics


Formulas are a special language used on Conjointly to perform tasks such as:

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 data types 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 or FALSE).
  • Undefined, which is a special value that is returned when a variable is not defined. When formulas are used in piping inside the survey, an undefined value will be shown as 🤷.

Algebraic functions

Algebraic functions perform basic mathematical operations. They always return a number.

OperationSyntaxExample usageResult
Additionx+y20+1535
Subtractionx-y10-37
Multiplicationx*y7*321
Divisionx/y10/25
Exponentialx^y4^216

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 is undefined.
  • 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.

SituationFormulaResultComment
The GET variable gender is maleGETvariable("gender") * 50because male is forced into 0
The GET variable gender was not recordedGETvariable("gender") * 50because the empty string is forced into 0
The GET variable age is 20GETvariable("age") * 5100because age is converted into the number 20
"3" + 58because 3 is forced into the number 3
"male" + " bird"0because + does not work as a concatenator

Max and min functions

The max and min functions return the minimum or maximum value from a set of arguments. They always return a number.

FunctionDescriptionExample usageResult
max(item1, item2, [item3], ...)Returns the highest value among the provided argumentsmax(3, -9, 7.5)7.5
min(item1, item2, [item3], ...)Returns the lowest value among the provided argumentsmin(3, -9, 7.5)-9

Important notes:

  • The functions require at least 2 arguments.
  • A maximum of 500 arguments are allowed; if more are provided, only the first 500 are considered.
  • All arguments are converted to numbers following these rules:
    • All numbers are treated as double-precision floating point numbers (“numeric” type in R).
    • Strings that can be converted to numbers are converted (e.g., "25" becomes 25).
    • Strings that cannot be converted to numbers become 0 (including empty strings).
    • TRUE is converted to 1.
    • FALSE is converted to 0.
    • undefined values are converted to 0.
    • If a vector of numbers is supplied, operation is done on the first element of the vector only.
    • If an argument is a function, it is calculated first and its result is passed as an argument, which is then converted to a number according to the rules described above.

Example usages of min and max functions are provided below:

SituationFormulaResultComment
Arguments are numbers and stringmax(3, -9, "25", 8)25because string "25" is converted into number 25
Arguments are boolean valuesmin(TRUE, FALSE)0because TRUE is forced into 1, FALSE is forced into 0
Arguments are non-numeric stringsmax("cat", "", "4")4because "cat" and "" are forced into 0, "4" is converted into 4
Arguments include vectormax([1, 2, 30, -5], "10", 7)10because only first element of vector (1) is considered
Arguments are vector with booleanmin([FALSE, 2, 3], 10, TRUE)0because the first element of vector FALSE is forced into 0
Argument includes functionmax(wrongFormula(234), -5)0because wrongFormula returns undefined, which is forced into 0

Rounding formulas

Rounding formulas are used to adjust numerical values to a desired precision:

FunctionDescriptionExample usageResult
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.

SituationFormulaResultComment
The GET variable gender is maleround(GETvariable("gender"))0because male is forced into 0
The GET variable age is 20.02323212424toFixed(GETvariable("age"))20because age is converted into the number 20.02323212424
The GET variable age is 20.02323212424toFixed(GETvariable("age"),40)20because fractionDigits is misspecified and therefore assumed to be 0
The GET variable age is 20.02323212424toFixed(GETvariable("age"),-1.33)20because fractionDigits is misspecified and therefore assumed to be 0
The GET variable freq is -23.31ceil(GETvariable("freq"))-23because ceil rounds up

Comparison operators

Comparison operators are used to compare two variables. Comparisons operators always return TRUE or FALSE.

OperationSyntaxExample usageResult
Equalsx==y5==10FALSE
Not equalsx!=y10!=3TRUE
Greater thanx>y5>19FALSE
Equal to or greater thanx>=y4>=4TRUE
Less thanx<y6<10TRUE
Equal to or less thanx<=y5<=1FALSE

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" returns FALSE and "a"=="a" returns TRUE. Comparison is case-sensitive.
  • 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.
  • False values work as in JavaScript: undefined will be equated to 0, or "0", for an empty string, or FALSE (and vice versa).

Example usages of comparison operators are provided below.

SituationFormulaResultComment
The GET variable gender is maleGETvariable("gender") < 5TRUEbecause male is forced into 0
The GET variable gender was not recordedGETvariable("gender") < 5TRUEbecause the empty string is forced into 0
The GET variable gender was not recordedGETvariable("gender") == 0TRUEbecause the empty string is forced into 0
The GET variable gender was not recordedGETvariable("gender") != 0FALSEbecause the empty string is forced into 0
The GET variable age is 20GETvariable("age") < 5FALSEbecause age is converted into the number 20
"3" < 5TRUEbecause 3 is forced into the number 3
"5" < 4FALSEbecause 5 is forced into the number 5
"5" == 5TRUEbecause 5 is forced into the number 5
"male" < " bird"FALSEbecause both strings are forced into the number 0
"male" == "Male"FALSEbecause comparison is case-sensitive
"male" == "male"TRUE
"0" == ""FALSEbecause both values are strings and compared as such
0 == ""TRUEbecause the empty string is forced into 0
1.0000001 == 1.0000002TRUEbecause the absolute value of the difference is 0.0000001 < 0.000001
1.0000001 == 1.0000005TRUEbecause the absolute value of the difference is 0.0000004 < 0.000001
1.0000001 == 1.0000012FALSEbecause the absolute value of the difference is 0.0000011 > 0.000001
"" == FALSETRUEbecause 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.

OperationSyntaxExample usageResult
Not!x!(10==5)TRUE
Andx&yTRUE&(10==5)FALSE
Orx|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.

SituationFormulaResultComment
!0TRUEbecause 0!=0 is FALSE
!1FALSEbecause 1!=0 is TRUE
!-1FALSEbecause -1!=0 is TRUE
!""TRUEbecause ""!=0 is FALSE
1|0TRUE
9&7TRUEbecause 9!=0 is TRUE and 7!=0 is TRUE
!-0.00000001TRUEbecause -0.00000001!=0 is FALSE
!-0.001FALSEbecause -0.001!=0 is TRUE
The GET variable gender is maleGETvariable("gender") & 5FALSEbecause male is forced into 0
The GET variable gender was not recordedGETvariable(“gender”) | 5TRUEthe empty string is forced into 0, but 5!=0 is TRUE
The GET variable gender was not recordedGETvariable(“gender”) | 0FALSEbecause the empty string is forced into 0
The GET variable gender was not recordedGETvariable("gender") & 0FALSEbecause the empty string is forced into 0
The GET variable age is 20!GETvariable("age")FALSEbecause 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 is TRUE or a different value if it is FALSE.
  • ifs('condition1', 'then1', ['condition2'], ['then2'], ..., ['else']) returns a value that corresponds to the first TRUE condition, or the “else” value if all specified conditions are FALSE.

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:

FormulaResultComment
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")undefinedbecause the function wrongFormula does not exist

Example usages of ifs are provided below:

FormulaResultComment
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)undefinedbecause 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)undefinedbecause undefined!=0 is FALSE, but so is "male"!=0 and the “else” condition is empty here
ifs(wrongFormula(234),4,"male")undefinedbecause the function wrongFormula does not exist