This article describes how to go from a table with NETs...
...to a table that groups or indents categories within each NET:
Requirements
A Nominal, Binary Multi, or Binary Multi (Compact) table with NETs that don't overlap between categories.
Method
1. Select your table.
2. Go to Data > Rules on the object inspector.
3. Click the Plus (+) button.
4. Select New custom rule (write your own JavaScript) > Edit JavaScript.
5. Paste the below into the dialog:
includeWeb("JavaScript Array Functions");
form.setHeading("Group rows according to NETs");
form.setSummary("Group rows according to NETs");
var blue_question = table.blueQuestion;
var data_reduction = blue_question.dataReduction;
var use_codes;
if (["Nominal", "Ordinal", "Binary - Multi (Compact)"].indexOf(blue_question.variableSetStructure) > -1)
use_codes = true;
else if (["Binary - Multi"].indexOf(blue_question.variableSetStructure) > -1)
use_codes = false;
else
form.ruleNotApplicable("the question selected in the Rows drop-down is not Binary - Multi, Nominal, or Binary Multi - Compact");
if (arrayHasDuplicateElements(table.rowLabels))
form.ruleNotApplicable("there are duplicate row labels in the table")
var indent_label = " - ";
// Row weights are used to keep children in the correct order.
var row_weights = {};
// Find underlying row sources
var row_values = table.rowLabels
.filter(function (label) {
return label !== 'NET';
})
.map(function (label, i) {
row_weights[label] = i;
return {
label: label,
sources: use_codes
? data_reduction.getUnderlyingValues(label)
: data_reduction.getUnderlyingVariables(label).map(function (v) {
return v.name;
})
}
});
// Create a map of the rows that are sourced from a single variable
var individual_values_map = {};
row_values
.filter(function (value) {
return value.sources.length === 1;
})
.forEach(function (value) {
individual_values_map[value.sources[0]] = {label: value.label, source: value.sources[0]}
});
// Populate the rows with multiple sources with their visible individual row data
var net_values = row_values
.filter(function (value) {
return value.sources.length > 1;
})
.map(function (value) {
var new_value = {
label: value.label,
sources: value.sources,
children: value.sources
.map(function (source) {
return individual_values_map[source];
})
.filter(function (source) {
return typeof source !== 'undefined'
})
};
new_value.children.sort(function (a, b) {
return row_weights[b.label] - row_weights[a.label];
});
return new_value;
});
// Create an array to store the labels that have been updated.
var changed_row_labels_map = {};
for (var i = 0; i < net_values.length; i++) {
var value = net_values[i];
value.children.forEach(function (child) {
table.moveRowAfter(table.rowIndex(child.label), table.rowIndex(value.label));
changed_row_labels_map[child.label] = indent_label + child.label;
});
}
table.rowLabels = table.rowLabels.map(function (label) {
return typeof changed_row_labels_map[label] !== 'undefined' ? changed_row_labels_map[label] : label;
});
- This code first checks that the underlying variable in the table is of the correct data type.
- It then loops through the underlying categories for each NET and places them directly below the relevant NET with an indent character prefixed to the label.
6. OPTIONAL: Change indent_label to include a different indent character for the categories within each NET.
7. Press the blue Play button > OK > OK.
8. OPTIONAL: To additionally sort your table from highest to lowest, for example, you will need to apply a sorting rule via Data > Rules > Plus (+) > Sort/Reorder Rows or Columns > Sort Rows (Automatically Updates When Data Changes). See How to Automatically Sort Table Rows for further details.
Next
How to Modify Table Rows and Columns Using a Rule
How to Automatically Sort Table Rows