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 thenewJavaScriptVariablearguments. - We specify the condition
q4 < 4 ? 1: 0to 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
falseas we wish to return a numeric variable. We would instead usetrueto 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
nullto 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 thenewRVariablearguments. - 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
nullto 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
preventDuplicateQuestionNameandpreventDuplicateVariableNamefunctions 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
getVariableByNameand 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_fileso 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_nameandcondition. The function declares the following JavaScript variables:-
data_fileis the project's data set. -
qis thequestionobject generated by usinggetQuestionByNamewith the function argument'squestion_nameargument. -
q_varsstores all the variables from thequestionobject. -
qtstores the Question Type. -
is_textreturns true or false if the Question Type is text. -
rebased_varsis set as an empty array. -
laststores the index of the last variable. - We use a
for…loopto iterate over each variable in our variable set usingjas the index.
-
expressionstores the function's condition argument to wrap within anif…elsestatement. The\r\nforces a line break in the code. -
new_v_nameis wrapped inpreventDuplicateVariableNameto ensure the variable name as a string with "rebased" appended doesn't already exist. -
rebased_varusesnewJavaScriptVariableto create the variable using the expression, text format, variable name, variable label, and position. -
rebased_varis added to the emptyrebased_varsarray. -
lastis reset as the last index so when it loops through again it will add the next variable directly after the previous one.
-
-
new_q_nameis wrapped in thepreventDuplicateQuestionNamefunction to ensure the question name with " - rebased" appended does not already exist. -
new_questionuses thesetQuestionfunction to combine therebased_varsvariables using our updated question name and same question type as the original. - If the Question Type is not text, we use the
copyValueAttributesForQuestionfunction to copy the variable and question characteristics ofqover tonew_question.
-
- Finally, to use our
rebaseQuestionfunction with our example, we setQ5asquestion_nameandq4 > 3ascondition.
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