Introduction
A value assignment is a survey element that fills a variable within an interview with certain content. It can be used for these 3 types of variables:
- survey variable (e.g. to pre-populate answers)
- sample/panel variable (e.g. to transfer answers into a sample/panel)
- custom variable (e.g. to store a calculated score)
A custom variable does neither belong to a question nor to a sample/panel. It is only available within the survey for which it was created for. Creating a custom variable requires a value assignment that is added to the survey by using the “Add content” menu. Click on the “Create variable” button in the settings on the right hand side of the screen. A box opens where variable name and data type must be defined.
Execution options
Value assignments can be added anywhere in the survey. However, a value assignment always generates a page break right before. Like in almost all other survey elements you can add filters to show (=execute) or hide (=skip) a value assignment. Furthermore, there are 4 options to control the execution behaviour of a value assignment:
- on survey loading
- one time
- every time (default setting)
- anytime
Execution Option | Description |
---|---|
on survey loading | The value assignment will only be executed under these two circumstances: – if an interview is loaded (also when continuing after intermission) – if the interview language is changed and the interview therefore is newly loaded |
only one time when the participant passes this point | The value assignment will be executed only once when the participant reaches this point of the survey. In case a filter skips the value assignment, it will be treated as “not yet executed”. If the participant would come back to this point later and the filter condition would then show the value assignment, it will be executed this time. |
every time the participant passes this point | The value assignment will be executed every time the participant reaches this point of the survey, no matter how often the participant uses the back button and goes forward again (by using the next button on the survey page before). |
anytime (immediately after every change to an involved variable) | The value assignment will be executed right away after the participant has typed-in or changed an answer and before the next button is clicked. This way you can show dynamic content according to the answers of the participant (e.g. automatic sum calculation). |
Basic functions
The content that should be assigned to a variable can be a number, a text, a date etc. according to the data type of the variable. In addition, calculations, numerical and string functions are available which will be shown and described afterwards. We will start with the elementary functions:
Assigning a calculated value to a variable, you can use the basic arithmetics:
- Addition: +
- Subtraction: –
- Multiplication: *
- Division: /
With the help of brackets ( ) the priorities of certain calculation parts can be shifted.
Automatic sum example
The participant should register the turnover for each region. The total sum will be calculated automatically.
The best question type for this task would be a matrix question (the example uses the variable name “turnover”). The matrix grid has 1 column (data input “Text” and data type “Integer number”) and 4 rows, one for each region. There is a 5th row for the total sum. Since the sum should be calculated immediately, the value assignment must be set to “anytime” execution. A value assignment with “anytime” execution can be placed anywhere. It is recommendable to place the value assignment at the beginning of that survey page or right afterwards.
** autosum (anytime execution)
turnover_5_1 = turnover_1_1 + turnover_2_1 + turnover_3_1 + turnover_4_1
** read only setting
setSurveyFieldsReadOnly(turnover_5_1)
The value assignment has no variable selected. In first row the name of the target variable turnover_5_1 is written down instead. Behind the equals sign the sum to calculate follows. Since the participant should not fill-in the sum by himself, the function setSurveyFieldsReadOnly() is used to set the field that corresponds to the sum variable to “read only” mode. In case the exact variable names are unknown, you can export the (filled or empty) raw data file on Analyze page and look into the code plan.
Besides the basic arithmetics there are more numerical functions available. The following examples show the frequently used other numerical functions:
- square (raise to the power of …)
- square root
- round to decimal
- modulus (remainder after division by …)
** auxiliary variable
a = 5
** square and root
integer1 = a^2
real1 = sqrt(a)
** round to … decimal
real2 = round(real1,2)
** modulus (remainder after division by …)
integer2 = a%2
The calculated variable values (shown in a textblock) look like this:
Furthermore, there are numerical functions that process more than one variable, e.g. random selection or statistical calculations. The following examples show:
- randomization and random number
- arithmetic mean
- arithmetic mean recognizing N/A answers and missings
** auxiliary variables
a1 = 2
a2 = 3
a3 = 5
a4 = null
min = 2
max = 5
** randomization and random number
integer3 = pickRandom([a1,a2,a3])
integer4 = randomInt(min,max)
** arithmetic mean
real3 = mean(a1,a2,a3)
** arithmetic mean recognizing N/A answers and missings
naFilter(x) = x!=0 and x!=null
real3 = mean(filter([a1,a2,a3,a4],naFilter))
The randomization sorts a given list of variables by random. Using the function pickRandom() the first element of the randomized variable list is returned. The random number that is created with the function randomInt() is a randomly chosen integer number between a minimum and a maximum value (minimum value included and maximum value excluded). The function mean() is one example of typical statistical calculations. In case there are missings within the answers, you need to filter them out. For this purpose the custom function naFilter is created. The calculated values (shown in a textblock) look like this:
The value assignments cannot only be used for numerical transformations but also for string content. The most important string functions are:
- concatenation
- substring verification
- text comparison
** auxiliary variables
postalcode = "CH-8005"
town = "Zürich"
** concatenation
text1 = concat(postalcode," ",town)
** substring verification
text2 = postalcode[4:7]
integer1 = indexOf(postalcode,"8005")
integer2 = indexOf(postalcode,"5008")
** text comparison
boolean1 = equals(town,"Zürich")
boolean2 = equals(town,"Utrecht")
The variable values from the examples (shown in a textblock) look like this:
To concatenate texts you have to put the texts/variables comma separated into the function concat(). To extract a substring starting and ending at certain positions the start and end positions have to be written down separated by a colon into square brackets that follow the string variable. If you are looking for a specific substring, use the indexOf() function and write down the text variable and the substring you are looking for inside brackets. Attention, the very first character has position 0. If the searched substring does not occur, the result is -1. The last example shows one successful and one failed text comparison. The result is either “true” or “false” (in each interview language, the English expressions are returned).
The text comparison, as shown in the example above, is the only way to create a filter condition that checks the exact match of the contents of two text variables.
Value assignments can be used for dates that are to be checked during the current interview to verify whether they are within a certain time span, are before or after a fixed date or do not exceed a maximum deviation from the current date. To do this, the date is converted into a date timestamp, which is nothing more than a consecutive number that starts with 0 at a fixed point in time in the past and progresses practically to infinity. Each date has a distinctive timestamp. The difference between the time stamps of two consecutive days is always identical.
The date2number() function determines the timestamp of the specified date (at 0 o’clock UTC) to the nearest millisecond. A day has 86 400 000 milliseconds, so the timestamp divided by 86 400 000 indicates the number of days since the start time in the past. If one wants to compare a specified date with the current day of the interview, then one can determine the timestamp of the interview date using the function today() and then work out the difference. In the value assignment it would look like this:
** date timestamp of participant answer stored in variable "date"
integer1 = date2number(date)/86400000
** date timestamp of today
integer2 = date2number(today())/86400000
** difference (number of days) between participant answer and today
integer3 = integer1 - integer2
Value assignments in calculation filters
A small tip regarding filter conditions: In filter conditions of the ‘calculation’ type, you can compare variables and/or calculations with each other. The corresponding fields use the same functions as value assignments, so in principle all functions presented here can equally be used in calculation filters.
Checking a constant sum is an example of a calculation filter with numerical variable values. Initial situation: The participant is to distribute exactly 100 points or 100% to the listed options. One now adds a validation that is to display a validation text with the help of a filter, if the sum does not add up to 100. The filter of the ‘calculation’ type uses the basic functions of the basic arithmetic operations. On the left side, the variables of the individual options are added together. On the right side, the value 100 is entered. Both are matched:
A calculation filter for text variables which is to check whether two variables share exactly the same content must use the equals() function, which was displayed at the text functions. The input on the right side of the calculation filter cannot distinguish whether it is text or a variable name. Basically, text will be assumed. Thus, the text comparison is to be set up using the mentioned function and the values “true” or “false”:
The calculation filter is also used when comparing two dates. Both dates are converted into numerical timestamps – as described with the date functions – which then enable a comparison. The date2number() function being used can be specified on the left as well as on the right in the filter condition.
Complex functions
For complex use cases or for scientific use, various advanced functions are available. Some of them are listed below. The value assignments use the Math.js library. As such, the Math.js online documentation can be consulted for further information. For customers without an SLA (Service Level Agreement), there is no further support related to these complex functions.
To control the behaviour of the Next button and the Back button, the following functions are available:
- Display the Next button only after a specified number of seconds
- Automatically click the Next button after a specified number of seconds
- Hide the Next button and automatically click it after a specified number of seconds
- Hide the Back button
** hide next button for 5 seconds
NextButton("hide",5)
** click next button automatically after 5 seconds
NextButton("click",5)
** hide next button and click automatically after 5 seconds
NextButton("hideandclick",5)
** hide back button
BackButton("hide")
The buttons will always appear at the end of a page. A value assignment always creates a page break immediately before it. Therefore, the value assignment with the button functions must be positioned at the beginning of the required page. If there are any other value assignments at this location in the survey, they must be inserted before the value assignment with the button functions. The default option “every time” should be selected as the execution option.
In some situations, the data are stored in variables whose data type restricts further processing of the data and therefore requires a conversion of the data type. Usually these are numbers that are stored in a text variable. Or the other way round, one would like to have numbers (e.g. year numbers) formatted in a fixed way without automatic thousand separators, so that they should be stored in a text variable. The following are the most important functions for converting data types:
** conversion string to integer number
integer1 = parseNumber("12345")
** conversion string to real number
real1 = parseReal("12345.67")
** conversion real or integer number to string
text1 = convertToString(12345.670)
Viewing the contents of the new variable (displayed in a text block) shows the numbers that were previously stored as text with number layouts (thousands and decimal separators as well as exactly 3 decimal places for fractions/real numbers). The former fractional/real number, which is now in a text variable, has no number layout and the last 0 (3rd decimal place) was automatically removed:
If you want to define a variable in a different way depending on the contents of another variable, you can use the If-Then-Else function. This function uses a special syntax which must be followed exactly:
If-condition ? Then-statement : Else-statement
The colon (introduction to the Else-statement) is mandatory. It must always be followed by a statement which, for example, may also be variableXY=variableXY and which does not trigger any action. If an as-is comparison of variables and values occurs in the If-condition, a double equal sign must be used. The single equal sign is always an assignment, never a comparison. And if you nest several If-Then-Else functions inside each other because there are more than just 2 different expressions, then the above syntax must be followed meticulously at each level of nesting. It is recommended to work with brackets for convenience, but they are not obligatory.
** basic if-then-else clause example
integer1==2 ? integer2=5 : integer2=integer2
** nested if-then-else clause example
integer1==2 ? integer2=5 : (integer1==3 ? integer2=7 : integer2=11)
The list function facilitates the creation of questions which always use the same answer options but should only display those flagged as known in the first question. Using filters that have to be set individually for each answer option, this can be done quite time-consumingly without any value assignments. The function shown here saves the survey programmer from having to create many individual filters.
The initial situation for the example is as follows: In a first question with the variable name “brand”, a long list of e.g. mineral water brands is shown. The participant should tick all known brands in this multiple choice question. In the follow-up question (a single-choice question with the variable name “bestbrand”), the participant is asked for his/her favourite brand. Of course, only the brands previously marked as known should be displayed. In the value assignment between the two questions, one records the visibility and the setChoicesVisibility functions:
** function that returns true or false for each answer option of "brand" question
visibility(choice) = answer(concat('brand_',choice.code)) == 1 ? true : false
** setChoicesVisibility processes the visibility function for "bestbrand" question
setChoicesVisibility('bestbrand',visibility)
In order to use the list function, a few things must be observed:
- The first question must be a multiple choice question. Each answer option has a separate variable consisting of the variable name (“brand”), an underscore and the variable suffix for the corresponding answer option. In the visibility function, the underscore must be entered after the variable name for the concat() function to determine the correct labels.
- The follow-up questions must use exactly the same variable suffixes (or values in the case of single choice questions) for the answer options as the first question, as the linkage is made via these variable suffixes. The labels may well be formulated differently.
- The follow-up questions cannot include any additional answer options outside those in the list. Only the N/A option is additionally possible.
- If the follow-up question is a matrix question, then the list function will be applied to the rows. The variable suffixes of the rows must then match the variable suffixes of the answer options from the first question.
- The visibility function is a user-defined function. Therefore, it can be named differently. You can also create several such functions with different names to allow several different lists to be used in a survey.
Using certain functions, the answers of all previous participants in the survey can be counted in value assignments and be made available in the interview. On the one hand, there are functions that count all interviews in the respective status (example 1). On the other hand, there is a function which allows you to define the counting condition yourself (example 2).
Example 1 shows the functions for counting all finished and all started interviews of this survey. The participant’s interview belongs to the started interviews at the moment of counting. If the interview has been finished, it changes to the completed interviews.
** get the total of all started or completed interviews
counter1 = survey.count_started
counter2 = survey.count_completed
The situation for example 2 is as follows. An event is offered repeatedly at different times, so that every participant who wants to register can freely choose his or her date. However, the capacities are limited. If a date is fully booked, it must be hidden from the selection. To do this, you need information as regards the number of registrations for each single date. The date selection is carried out via a single choice question with the variable name “eventtime”. Only completed interviews are counted. This is how the value assignment would look like:
** get the total of each answer (only completed interviews)
counter1 = countInterviews(eventtime==1 and survey.State=='Completed')
counter2 = countInterviews(eventtime==2 and survey.State=='Completed')
counter3 = countInterviews(eventtime==3 and survey.State=='Completed')
counter4 = countInterviews(eventtime==4 and survey.State=='Completed')
The countInterviews() function can generally contain any filter condition. If several variables are used, they can be linked with “and” or “or”. The same priority rules apply as with the element filters. If the interview status is to be part of the filter condition, the descriptions must be selected that are also found in the raw data export under “Status” (no difference in various interview languages).
When you create a custom member variable, you can select “Matrix” and “JSON” as a data type. These are two special data types for specific functions which can be explained in detail in a chargeable training course. Below is an example of how to fill a matrix and a JSON variable:
** matrix with 2 rows and 3 columns
matrix1 = [[1,-3,2],[1,2,7]]
** json with typical tree structure
json1 = toJSON({"tree":[{"branch1":[{"name":"new","leaves":12}]},{"branch2":[{"name":"old","leaves":null}]}]})
** access values of a matrix in place holder scope.
{{=matrix1[ROW-ID,COLUMN-ID]}}
A matrix can be used to perform the usual calculations such as addition and multiplication. A JSON variable can be used as an extensive list (e.g. postal codes and corresponding city names) that can be accessed from the survey.