31 July 2018 | by Matt Steele

Tutorial: Creating and Working with JavaScript Variables in Q

It’s easier than you think to use basic JavaScript to make new variables! We”ll show you via a worked example in Q how to combine, split and transform data into new variables using conditional ‘if’ statements and some Boolean logic (“and”, “or”).

Why create new variables in Q?

Generating a new variable using code can create some flexible and powerful results. The beauty of creating variables in Q is that they update automatically in the project. You never need to write the code again. You can also easily go back and edit variables later if you want to tweak the code.

If you haven’t seen it already, you may find it worthwhile also watching the short video on how to create JavaScript variables.  You can find links at the end to further reading and references on the Q wiki.

How to create JavaScript variables in Q

Create a JavaScript variable via the Create menu in Q (Create > Variables and Questions > Variables > JavaScript Formula). This is also accessible via a right-click in the Variables and Questions tab. You’ll notice that you have a choice of creating a numeric or a text variable. For the purposes of simplicity, let’s consider only numeric variables for now.

A window will pop open asking you for an expression. An example is shown below:

JavaScript expression window

You need to write (or paste) a JavaScript expression (which means a bit of programming code) into the Expression window. The Expression window works with variable Names (not labels). At the top there is a list and search function that allows you to look up variables by label. You can double-click on any line in the variable list and it will insert that variable’s Name into the Expression window.

A worked example

In our example we have collected data on the number of colas and the 6 different sub-types of cola people consumed while ‘out and about’. This forms 6 different numeric variables. To find the sum of the variables with JavaScript, the expression is: q2a_1 + q2a_2 + q2a_3 + q2a_4 + q2a_5 + q2a_6.

But how do you work out what expression you need? Q helps you write your own by highlighting each of the variable names when it recognizes them.

These are referred to as the input variables. Below the Expression window, you can see a Preview of results. This is useful for checking that your expression is working correctly.

You can see the individual values of the input variables in each column before the Result column. Each line represents a different case in the data file. In our example, we can see that the sum works perfectly for case number one (the first line), as 1 + 12 gives us the result, 13.

In the preview panel, it can be useful to toggle the Collapse Duplicate Inputs box at the bottom. This option compresses the cases with identical input variables into a single line. It enables you to efficiently check that the different combinations of input variables work correctly in your expression.

Banding a numeric variable

Suppose the expression in the above example resulted in a new numeric variable called “sumCola”. You might like to then create an additional variable that allocates people to one of three categories based on their total cola consumption (Light Drinkers – less than 5 colas, Medium Drinkers – between 5-10 colas, and Heavy Drinkers – more than 10 colas).

The if command allows you to do this. An example is shown below:

if (sumCola < 5) 1; else if (sumCol>= 5 && sumCola <= 10) 2; else if (sumCola > 10) 3; 
else NaN; 

Line 1 starts the if expression. It effectively says “If the variable sumCola is less than 5, then return a 1”. The next line continues the story with an if else statement. It says “if the first bit (line 1) doesn’t work out, then consider that if the variable sumCola is greater than or equal to 5 and (represented by the &&) less than or equal to 10 (i.e. falls between 5 and 10), then return a “2”. Line 3 follows suit. With line 4, we’re rounding off the expression by saying “anything left over, consider it missing “. NaN stands for Not-A-Number (i.e. missing or blank)

The resultant variable will have the values of 1, 2, or 3 (and perhaps missing values). Because we want this to act as a categorical variable (i.e. Pick One question), you then need to do two things. First, change the variable type to Categorical (that will make it a Pick One question). Then you set the Value labels as you like (e.g. 1 = “Light Drinker”, 2 = “Medium Drinker” and 3 =  “Heavy Drinker”).

You can create bandings via merging in the Outputs tab. However when you receive new data, if there are any new values in the result (e.g. suddenly a new case has a total 50 colas), they will need to be manually merged into one of the three categories. The beauty of using the JavaScript variable is that automatically allocates any new results to the appropriate category.

You could also put all the above into the one variable, rather than splitting it over two. You can make variables within the JavaScript variable. In the following example, we create a new variable within the JavaScript variable called x:

x = q2a_1 + q2a_2 + q2a_3 + q2a_4 + q2a_5 + q2a_6;
if (x > 5) 1;
else if (x <= 5 && x >= 10) 2; 
else if (x < 10) 3; 
else NaN;

Combining different weighting variables

In the above examples, the JavaScript variables are returning constants. But JavaScript variables can return the values from other variables as well. A common application is the need to combine the weights for various segments into the one variable. This can also come in handy when the Merge Question function doesn’t work, because cases may have values on multiple variables.

Consider a situation where we’ve collected data for 4 countries (UK, France, Australia, Japan). The data for each country was held in 4 separate data files, but merged together into the one final file. Membership to a particular segment (market) is defined by a variable called country. Each country’s data file had a specific weighting variable, so in the merged data file we now have 4 weighting variables (weight_UK, weight_FR, weight_AU, weight_JP). When we do our analysis, we only want to deal with one weighting variable, so let’s combine them into one using JavaScript.

if (country == 1) weight_UK; 
else if (country == 3) weight_FR;  
else if (country == 7) weight_AU;
else if (country == 4) weight_JP; 
else NaN; 

You’ll notice that there are two consecutive equals signs in the above expression. You need both of them because in JavaScript a single equals sign has a different role. In short, a single equals sign is used when you’re setting a variable as something (also called assigning a value), as in the example above with the variable called x). The double-equal sign indicates a comparison.

You may also notice that the values of the country variable are not sequential. That’s because, in our hypothetical example, the variable country has values of 1 = UK, 2 = Germany, 3 = France, 4 = Japan, etc. You can conveniently look up a variable’s value via a right-click in the variable list just above the Expression window. You can also toggle on Show Labels in the preview panel at the bottom (to guide your sense checking).

Making a date variable from a categorical variable

In Q, JavaScript (like R) has a suite of handy ready-made functions that can help you do great things. One such function is called Q.EncodeDate(). It will enable you to return a number in a format that Q can in turn recognize as a date question. Used in conjunction with conditional statements, this can enable you to turn a categorical variable (e.g. period or wave variable) into a date question. Date questions have numerous benefits in Q, such as automatic aggregation of time, testing (significance) against the previous period, specific filter functions, and more (as outlined here).

Suppose you have a variable in your data file called week. It encodes the week of the survey, but in categorical format. As a result it just encodes values such as 1 = week 1, 2 = week 2, 3 = week 3, and so on. If you want to turn this into a date question, starting the first week on the 1st Jan 2018, then you can do so in Q, using an expression like the below. Notice that Q.EncodeDate works with yyyy,mm,dd. You can see that in the Common Methods panel on the right-hand side of the script window.

if (week == 1) Q.EncodeDate(2018,01,01); 
else if (week == 2) Q.EncodeDate(2018,01,08); 
else if (week == 3) Q.EncodeDate(2018,01,15); 
else if (week == 4) Q.EncodeDate(2018,01,22); 
else if (week == 5) Q.EncodeDate(2018,01,29); 
else if (week == 6) Q.EncodeDate(2018,02,05); 
else NaN; 

You need then only change the variable type to Date, in order for Q to use it as a date question.

Working with JavaScript text variables

JavaScript text variables create, unsurprisingly, a text variable which is useful if you want to join together the results of different open-ended variables. The following joins together 3 spontaneous brand awareness questions into one text variable, and inserts punctuation. It could be thought of as akin to the concatenate function in Excel.

q1a_1 + ", " + q1a_b + ", " + q1a_c + "."

If you aim to create create a categorical variable, as in the first example with Light-Heavy drinkers, then you can use a text JavaScript variable to automatically generate the labels. Q automatically sets up value labels when converting a text variable to a categorical variable. If you make a numeric variable, you may need to assign labels to the values manually (e.g. 1 = Segment A, 2 = Segment B) as per the first example in this post. The first example (summing the colas) could be rewritten as a text variable with the following:

if (sumCola > 5) "Light Drinker";
else if (sumCola <= 5 && sumCola <= 10) "Medium Drinker"; else if (sumCola > 10) "Heavy Drinker";
else "";

Tips when working with code

Writing in computer code needs to be exact – you need to pay attention to:

  • the presence or absence of semi-colons (they signal that you’re ready for the next bit of the expression);
  • the capitalization of letters (case sensitivity means that “if” does not mean the same as “If” or “IF”)
  • the right number of brackets (and where they open/close)
  • whether they are (round) or {curly} or [square] brackets
  • when symbols are doubled. In the above examples you need two ampersands to make the “AND” logic work, and we’ve discussed the need for two equal signs when comparing values. An “OR” uses two | character (called “pipe”), thus: ||.  On a standard US keyboard, this can be typed by holding Shift and pressing the button directly above Enter.
  • the presence of missing values with your input variables. Missing values in the inputs can lead to missing results if not handled correctly. There is more elaborate code you can use to make conditional statements around missing values.

The good news is that with all these details, the expression input window in Q will check your code for you. It’s designed to help you pin-point when things are slightly off. The variable won’t be created at all if there is a problem with the expression.

Further reading and references

This QPack has all the examples above stored as variables (the first six variables). Right-click on the variables (in the Variables and Questions tab) and select Edit Variable to see the expressions at work.

Don’t forget to check out the Mathematical Functions within the Ready Made Formula(s), as these can be good shortcuts to making JavaScript variables. And they deal with missing data (incomplete cases) as well.

There are also plenty of (free) JavaScript resources beyond the Q wiki to help you learn more.

Author: Matt Steele

Matt has over 14 years of experience in the marketing research arena, with a combination of research experience (qualitative and quantitative), marketing training, academic psychology (cognitive), creative leadership, geekiness and artistic flair. He currently works for Displayr (the home of Q and Displayr) and is based in London: supporting, selling, marketing and training for Q research software and associated software packages (eg: Displayr). He holds a Honours degree in Psychology from UNSW, a Grad Cert. in Marketing from UTS, and a Grad Dip in Directing from NIDA (all based in Sydney, Australia).

No comment. Share your thoughts.

Leave a Reply

Your email address will not be published. Required fields are marked *