Requirements
- The importdata.zip file which includes the Phone data set that we will use for this article.
- You have read How to Create a Custom QScript, How to Work with Variables via QScript and How to Modify Variables and Value Attributes via QScript.
- This assumes you have also a regrouped variable set called Q5 as per the steps in the Combine section of How to Modify Variables and Value Attributes via QScript.
- You are using one of the methods from How to Use QScripts in Q.
Method
Q has dedicated functions for creating JavaScript and R variables. Let's use a simple example where we wish to create a variable that identifies anyone who is under 25 based on our Age variable (q4).
Creating a JavaScript variable
To create this using a JavaScript variable, we would use the newJavaScriptVariable
function:
project.dataFiles[0].newJavaScriptVariable("q4 < 4 ? 1 : 0", false,
"lessThan25", "Less than 25", null);
- We first tell it to add this new variable to our primary data set using
project.dataFiles[0]
and then set thenewJavaScriptVariable
arguments. - We specify the condition
q4 < 4 ? 1: 0
to return a 1 if q4 includes category values 1 through 3, i.e. less than 4, for all the ages under 25. - We set the second argument to
false
as we wish to return a numeric variable. We would instead usetrue
to return a text variable. - We then specify the new variable name.
- Now we specify the new variable label.
- Finally, we set the position index. In this case, we will leave this as
null
to append the new variable to the top of the data set. You can, however, specify an exact row index.
Creating an R variable
To create this using an R variable, we would use the newRVariable
function:
project.dataFiles[0].newRVariable('q4 %in% c("15 and under","16-19 years","20-24 years")',
"lessThan25", "Less than 25", null);
- We first tell it to add this new variable to our primary data set using
project.dataFiles[0]
and then set thenewRVariable
arguments. - We specify the condition
q4 %in% c("15 and under","16-19 years","20-24 years")
to return a 1 if q4 includes these 3 category labels for all the ages under 25. - We then specify the new variable name.
- Now we specify the new variable label.
- Finally, we set the position index. In this case, we will leave this as
null
to append the new variable to the top of the data set. You can, however, specify an exact row index.
Advanced examples
1. Creating a filter
Now let's look at a more advanced version of this example where we turn this new variable into a filter and perform additional validation and formatting functions:
// Add library
includeWeb('QScript Utility Functions');
// Set data file to add variable to
var data_file = project.dataFiles[0];
// Validate name/label
var q_name = preventDuplicateQuestionName(data_file, "Less than 25");
var var_name = preventDuplicateVariableName(data_file, "lessThan25");
// Set position of new variable
var position = data_file.getVariableByName('q4');
// Create new variable
var v = data_file.newJavaScriptVariable("q4 < 4 ? 1: 0", false, var_name, q_name, position);
// Set variable format
v.variableType = "Categorical";
v.valueAttributes.setLabel(0, "Not Selected");
v.valueAttributes.setLabel(1, "Selected");
v.question.isFilter = true;
- We use the
preventDuplicateQuestionName
andpreventDuplicateVariableName
functions from the QScript Utility Functions library to ensure there aren't already variables or questions with this name and label. Each variable and question needs to be unique in our data set, so these functions will append values to the name or label to ensure they can still be created without causing any conflict. By default the functions will attempt to use the specified text. - In order to have this new variable appear directly after our Age variable, we use
getVariableByName
and reference its variable name. - We then pass the name and position arguments into
newJavaScriptVariable
. In this case, we have already declared our data file asdata_file
so can simplify this command. - Finally, we set the variable type, add labels for each value, and set the variable as a filter.
2. Rebasing variables
The above examples create new variables without a code frame. However, there will be situations where you wish to recode a variable into another variable and copy the original code frame across or apply this to multiple variables.
The below example fits both criteria as it includes a custom function called rebaseQuestion
that we can use to create a rebased version of Q5 that removes any data for anyone under 25:
includeWeb('QScript Utility Functions');
includeWeb('QScript Value Attributes Functions');
function rebaseQuestion(question_name, condition) {
var data_file = project.dataFiles[0];
var q = data_file.getQuestionByName(question_name);
var q_vars = q.variables;
var qt = q.questionType;
var is_text = qt == "Text" || qt == "Text - Multi";
var rebased_vars = [];
var last = q_vars[q_vars.length-1];
// For each variable, create the appropriate rebased variable.
for (var j=0; j<q_vars.length; j++) {
var expression = "if (" + condition + ") "+ q_vars[j].name.toString() + ";\r\n else NaN";
var new_v_name = preventDuplicateVariableName(data_file, q_vars[j].name.toString() + "rebased");
var rebased_var = data_file.newJavaScriptVariable(expression, is_text, new_v_name ,q_vars[j].label.toString(), last);
rebased_vars.push(rebased_var);
last = rebased_var;
}
var new_q_name = preventDuplicateQuestionName(data_file, q.name + " - rebased");
var new_question = data_file.setQuestion(new_q_name, qt, rebased_vars);
if (!is_text)
copyValueAttributesForQuestion(q, new_question);
}
rebaseQuestion("Q5","q4 > 3");
- We start by including references to the QScript Utility Functions and QScript Value Attributes Functions library so we can use some pre-built functions.
- Next, we build the function to include two arguments:
question_name
andcondition
. The function declares the following JavaScript variables:-
data_file
is the project's data set. -
q
is thequestion
object generated by usinggetQuestionByName
with the function argument'squestion_name
argument. -
q_vars
stores all the variables from thequestion
object. -
qt
stores the Question Type. -
is_text
returns true or false if the Question Type is text. -
rebased_vars
is set as an empty array. -
last
stores the index of the last variable. - We use a
for…loop
to iterate over each variable in our variable set usingj
as the index.
-
expression
stores the function's condition argument to wrap within anif…else
statement. The\r\n
forces a line break in the code. -
new_v_name
is wrapped inpreventDuplicateVariableName
to ensure the variable name as a string with "rebased" appended doesn't already exist. -
rebased_var
usesnewJavaScriptVariable
to create the variable using the expression, text format, variable name, variable label, and position. -
rebased_var
is added to the emptyrebased_vars
array. -
last
is reset as the last index so when it loops through again it will add the next variable directly after the previous one.
-
-
new_q_name
is wrapped in thepreventDuplicateQuestionName
function to ensure the question name with " - rebased" appended does not already exist. -
new_question
uses thesetQuestion
function to combine therebased_vars
variables using our updated question name and same question type as the original. - If the Question Type is not text, we use the
copyValueAttributesForQuestion
function to copy the variable and question characteristics ofq
over tonew_question
.
-
- Finally, to use our
rebaseQuestion
function with our example, we setQ5
asquestion_name
andq4 > 3
ascondition
.
Next
How to Add Folders and Text Outputs via QScript
Later
How to Create Tables and R Calculations via QScript
How to Create a Chart via QScript
How to Modify Tables via QScript
See Also
How to Work with Variables via QScript
How to Modify Variables and Value Attributes via QScript