Filtering - Filters from Selected Data
Create a new filter for each category of the selected variable set(s)
This QScript creates a new filter for each category of the selected questions. These filters can then be applied to any tables and charts in the report.
Technical details
If you have selected a table on the Outputs tab or a variable or question on the Variables and Questions tab, then the function will run on the pre-selected table/question (assuming they're of a permissible type - see below). If you have nothing selected, then you will be presented with a list of the questions in the study, and you should select those that you wish to have filters created from. This list is restricted to questions of the type Pick One, Pick One - Multi, Pick Any, Pick Any - Grid, and Pick Any - Compact. The filters for a question are combined into to a new question, and a table is added to your report to show each of these new questions.
For Pick Any - Grid questions, a copy of the question is made and each variable is set as a filter. For all other question types this QScript will identify changes that have been made in the tables (e.g. merging and renaming of categories) and the filters that are created will reflect those changes.
How to apply this QScript
- Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
- Click on the QScript when it appears in the QScripts and Rules section of the search results.
OR
- Select Automate > Browse Online Library.
- Select this QScript from the list.
Customizing the QScript
This QScript is written in JavaScript and can be customized by copying and modifying the JavaScript.
Customizing QScripts in Q4.11 and more recent versions
- Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
- Hover your mouse over the QScript when it appears in the QScripts and Rules section of the search results.
- Press Edit a Copy (bottom-left corner of the preview).
- Modify the JavaScript (see QScripts for more detail on this).
- Either:
- Run the QScript, by pressing the blue triangle button.
- Save the QScript and run it at a later time, using Automate > Run QScript (Macro) from File.
Customizing QScripts in older versions
JavaScript
includeWeb('QScript Questionnaire Functions');
includeWeb('QScript Value Attributes Functions');
includeWeb('QScript Utility Functions');
includeWeb('QScript Selection Functions');
includeWeb('QScript Functions to Generate Outputs');
includeWeb('QScript Data Reduction Functions');
includeWeb('QScript Functions for Combining Categories');
if (!main())
conditionallyEmptyLog("QScript cancelled.");
else
conditionallyEmptyLog("QScript finished.");
function main() {
var web_mode = (!!Q.isOnTheWeb && Q.isOnTheWeb());
var allowed_types = ["Nominal", "Ordinal", "Nominal - Multi", "Ordinal - Multi", "Binary - Multi",
"Binary - Multi (Compact)", "Binary - Grid"];
var selected_questions = selectInputQuestions(allowed_types);
if (!selected_questions)
return false;
if (!areQuestionsValidAndNonEmpty(selected_questions))
return false;
var filter_questions = selected_questions.map(createFiltersForAllCategories);
filter_questions = filter_questions.filter(function (q) {
if (q != null) {insertAtHoverButtonIfShown(q); return true; } else return false; });
if (filter_questions.length == 0) {
log("The selected questions contain no data, or are not appropriate.");
return false;
}
reportNewRQuestion(filter_questions, "Filters");
return true;
}
function createFiltersForAllCategories(question, web_mode) {
var q_type = question.questionType;
var new_filter_question;
var new_name = preventDuplicateQuestionName(question.dataFile, question.name + " - Filters");
var merged_categories;
// Pick Any - Grid simply gets converted to a Pick Any because there is
// no way to treat merged categories.
if (q_type == "Pick Any - Grid") {
new_filter_question = question.duplicate(new_name);
new_filter_question.questionType = "Pick Any";
} else if (q_type == "Pick One - Multi") {
// Flatten and merge using existing methods
var merged_categories = getMergedCategoriesFromPickOne(question);
if (merged_categories == null || merged_categories.length == 0)
return null;
new_filter_question = pickOneMultiToPickAnyFlattenAndMergeByRows(question, merged_categories, true, false);
new_filter_question.name = preventDuplicateQuestionName(question.dataFile, new_filter_question.name.replace("(flattened)", "- Filters"));
new_filter_question.questionType = "Pick Any - Grid";
if (!new_filter_question.isValid)
{
new_filter_question.questionType = "Pick Any";
}
} else {
// For other question types we work out which categories are
// in the data reduction (excluding the main NET).
if (["Pick One", "Pick Any - Compact"].indexOf(q_type) > -1)
merged_categories = getMergedCategoriesFromPickOne(question);
else if (q_type == "Pick Any")
merged_categories = getMargedCategoriesFromPickAny(question);
else
throw "Not applicable for " + q_type + "questions.";
if (merged_categories == null)
return null;
// Create a new variable for each category in the data reduction
var variables = question.variables;
var data_file = question.dataFile;
var new_vars = [];
var num_vars = variables.length;
var last_var = variables[num_vars-1];
var new_name_prefix = "FILTER" + makeid() +"_";
merged_categories.forEach(function (obj, ind) {
var expression;
if(q_type == "Pick Any")
expression = mergePickAnyExpression(obj.variables);
else if (q_type == "Pick Any - Compact")
expression = mergePickAnyCompactExpression(variables.map(function (v) { return v.name; }), obj.values);
else if (q_type == "Pick One")
expression = mergePickOneExpression(variables[0].name, obj.values, true);
try {
var new_var = question.dataFile.newJavaScriptVariable(expression,
false,
new_name_prefix + ind + 1,
obj.name,
last_var,
{skipValidation: true, accelerate: true});
} catch (e) {
log("Could not create filter: " + e);
return false;
}
new_var.variableType = "Categorical";
last_var = new_var;
new_vars.push(new_var);
});
// Form the question
if (new_vars.length > 0) {
var new_q_name = preventDuplicateQuestionName(data_file, question.name + " - Filters");
var new_filter_question = data_file.setQuestion(new_q_name, "Pick Any", new_vars);
} else
return null;
}
// Set the properties of the new question
new_filter_question.isFilter = true;
setLabelForVariablesInQuestion(new_filter_question, 0, "Not Selected");
setLabelForVariablesInQuestion(new_filter_question, 1, "Selected");
return new_filter_question;
}
// Returns an array describing which categories in the pick one (- multi)
// question have been merged (excluding the NET). Each entry in the array has:
// - name: The name of the merged category
// - values: An array of the underlying values for the categories that have
// been merged
function getMergedCategoriesFromPickOne(q) {
var value_attributes = q.valueAttributes;
var non_missing_values = q.uniqueValues.filter(function (x) {
return !value_attributes.getIsMissingData(x);
}).sort();
// Get the set of values for each code in the data reduction
var merging_objects = getAllUnderlyingValues(q);
// Filter out the set of values corresoponding to the NET as
// we don't want to keep them.
merging_objects = merging_objects.filter(function (obj) {
return obj.array.sort().toString() != non_missing_values.toString();
});
merging_objects = merging_objects.map(function (obj) {
return { name: obj.label, values: obj.array };
});
return merging_objects;
}
// Returns an array describing the data reduction of a pick any question
// excluding the NET. Each entry in the array corresponds to a code from
// the data reduction, and has:
// - name: The name of the category.
// - variables: The names of the variables in the category.
function getMargedCategoriesFromPickAny(q) {
var data_reduction = q.dataReduction;
var net_labels = ["NET"];
if (fileFormatVersion() > 8.41)
net_labels = data_reduction.netRows.map(function (x) { return data_reduction.rowLabels[x]; });
var merging_objects = [];
data_reduction.rowLabels.forEach(function (label) {
if (net_labels.indexOf(label) == -1)
merging_objects.push({ name: label, variables: data_reduction.getUnderlyingVariables(label).map(function (v) { return v.name; }) });
});
return merging_objects;
}
// Generate an JavaScript expression for merged categories in a Pick Any question.
function mergePickAnyExpression(variable_names) {
var nan_bit = "isNaN(" + variable_names[0] + ")";
var main_bit = "(" + variable_names[0];
if (variable_names.length > 1) {
for (var j = 1; j < variable_names.length; j++) {
nan_bit += " || isNaN(" + variable_names[j] + ")";
main_bit += " || " + variable_names[j];
}
}
return nan_bit + " ? NaN : " + main_bit + ") ? 1 : 0;";
}
// Generate an JavaScript expression for merged categories in a Pick Any - Compact question.
function mergePickAnyCompactExpression(variable_names, codes) {
var missing_check = "(" + variable_names.map(function (name) { return "Q.IsMissing(" + name + ")"; } ).join(" && ") + ") ? NaN : (";
var term_array = [];
variable_names.forEach(function (name) {
codes.forEach(function (code) {
term_array.push("Q.Source(" + name + ") == " + code);
});
});
return missing_check + term_array.join(" || ") + ") ? 1 : 0;";
}
Prior to the 15th of December, 2015, this page was known as Create New Variables - Create Filters from Selected Data
See also
- QScript for more general information about QScripts.
- QScript Examples Library for other examples.
- Online JavaScript Libraries for the libraries of functions that can be used when writing QScripts.
- QScript Reference for information about how QScript can manipulate the different elements of a project.
- JavaScript for information about the JavaScript programming language.
- Table JavaScript and Plot JavaScript for tools for using JavaScript to modify the appearance of tables and charts.
Displayr - Anything Menu
Displayr - Filtering
Displayr - New Variable Menu
Q Technical Reference
Q Technical Reference
Q Technical Reference > Setting Up Data > Creating New Variables
Q Technical Reference > Updating and Automation > Automation Online Library
Q Technical Reference > Updating and Automation > JavaScript > QScript > QScript Examples Library > QScript Online Library