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.

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

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
"" == 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