Modifying the Whole Table or Plot - Unnest a Nested Banner on a Table

From Q
Jump to: navigation, search

This rule rule re-arranges a table which has a Banner selected in the Brown Drop-down Menu so that the spans from the banner appear in the rows instead of the columns. This rule requires that the banner selected in the Brown Drop-down Menu has a single pair of questions that are stacked on top of one another.

Example

The following table shows a Number question in the Blue Drop-down Menu and a nested Banner in the Brown Drop-down Menu. Sometimes it is useful to reshape the data by 'stacking' by one of the questions in the banner, to reorganize the table so that is appears like the lower table.

InitialBannerTable 2.PNG

UnnestedBannerTable 2.PNG

Note that due to the nature of the changes, this resulting table will not behave like a normal Q table. For example, you cannot drag-and-drop to rearrange rows and the NET categories will appear when you export.

Technical details

This rule does not apply when a Pick One - Multi, Pick Any - Grid, Number - Grid, Ranking, or Experiment question is selected in the Blue Drop-down Menu.

Statistics - Right and Statistics - Below are not available on a table that uses this rule.

Some statistics no longer make sense once the table has been rearranged and are not available. These statistics are:

  •  % Column Share
  •  % Row Share
  •  % Share
  •  % Total Responses
  •  % Column Responses
  •  % Row Responses
  • Index

Significance testing results are not available once the table has been rearranged.

How to apply this rule

For the first time in a project

  • Select the table(s)/chart(s) that you wish to apply the rule to.
  • Start typing the name of the Rule into the Search features and data box in the top right of the Q window.
  • Click on the Rule when it appears in the QScripts and Rules section of the search results.

OR

  • Select Automate > Browse Online Library.
  • Choose this rule from the list.

Additional applications of the rule

  • Select a table or chart that has the rule and any table(s)/chart(s) that you wish to apply the rule to.
  • Click on the Rules tab (bottom-left of the table/chart).
  • Select the rule that you wish to apply.
  • Click on the Apply drop-down and choose your desired option.
  • Check New items to have it automatically applied to new items that you create. Use Edit > Project Options > Save as Template to create a new project template that automatically uses this rule.

Removing the rule

  • Select the table(s)/chart(s) that you wish to remove the rule from.
  • Press the Rules tab (bottom-right corner).
  • Press Apply next to the rule you wish to remove and choose the appropriate option.

How to modify the rule

  • Click on the Rules tab (bottom-left of the table/chart).
  • Select the rule that you wish to modify.
  • Click Edit Rule and make the desired changes. Alternatively, you can use the JavaScript below to make your own rule (see Customizing Rules).

JavaScript

table.requireNumericTable();
table.requireOriginalRowsColumns();
includeWeb('Table JavaScript Utility Functions');
var rule_name = "Unnest a nested banner on a table";
form.setSummary(rule_name);
form.setHeading(rule_name);
 
// Prevent Statistics - Right and Statistics - Below
suppressOutputForRightTable("Statistics - Right are not available for this table. Remove any selections from the Statistics - Right menu.");
suppressOutputForBelowTable("Statistics - Below are not available for this table. Remove any selections from the Statistics - Below menu.");
 
// Check structure of table is appropriate
if (!questionInTableIs1D(table.blue))
	form.ruleNotApplicable('the question in the blue drop-down is a Pick One - Multi, Pick Any - Grid, or Number - Grid');
 
if (questionInTableIs1D(table.blue) && table.brown == "SUMMARY")
    form.ruleNotApplicable('this table does not have any column spans');
 
if (table.columnSpans.length == 0)
	form.ruleNotApplicable('this table does not have any column spans');
 
if (table.availableStatistics.indexOf("Coefficient") > 0)
	form.ruleNotApplicable('the question in the blue drop-down is an Experiment or Ranking')
 
var checkbox_footer = form.newCheckBox('footer', 'Show significance testing message in footer');
checkbox_footer.setDefault(true);
form.setInputControls([checkbox_footer]);
var add_footer = checkbox_footer.getValue();
 
preventAllSignificanceTesting(table, rule_name, add_footer);
 
// Detect Span Structure
var spans = table.columnSpans;
// Check whether the first span has a different length to subsequent spans
// If the length of the span is different then it indicates that the first span contains
// the other spans in the table.
var span_tidied = (spans[0].indices.length == spans[spans.length-1].indices.length); 
 
var num_spans;
if (span_tidied) 
	num_spans = spans.length;
else 
	num_spans = (spans.length - 1)/2;
 
var new_num_cols = spans[0].indices.length;
 
if (!(table.numberColumns-1 == num_spans*new_num_cols || table.numberColumns == num_spans*new_num_cols))
   form.ruleNotApplicable('this banner does not have a single pair of questions stacked on top of one another');
 
// Get Row and Column labels
var new_col_labels = table.columnLabels.slice(0, new_num_cols);
var cur_row_labels = table.rowLabels;
var new_row_labels = [];
 
if (span_tidied)
	for (var j = 0; j < spans.length; j++)
		new_row_labels.push(spans[j].label);
else
	for (var j = num_spans; j < 2*num_spans; j++)
		new_row_labels.push(spans[j].label);
 
// Build the new table
// Remove the final NET column
if (table.numberColumns > num_spans*new_num_cols)
table.deleteColumn(table.numberColumns-1);
 
// Figure out the size of the new table
var cur_num_rows = table.numberRows;
var new_num_rows = cur_num_rows*num_spans;
 
// Get the stats
var stats_array = [];
for (var j = 0; j < table.statistics.length; j++)
	stats_array.push(table.get(table.statistics[j]));
 
// Reshape the table
while (table.numberColumns > new_num_cols)
	table.deleteColumn(table.numberColumns-1);
 
while (table.numberRows < new_num_rows)
	table.insertRowAfter(table.numberRows-1, "");
 
// Determine the row labels and spans
if (cur_num_rows == 1) {
	table.rowLabels = new_row_labels;
} else {
	for (var j = 0; j < num_spans; j++) {
		var span_array = [];
		for (var k = j*cur_num_rows; k < (j+1)*cur_num_rows; k++)
			span_array.push(k);
		table.spanRows(span_array, new_row_labels[j]);
	}
	var repeated_row_labels = [];
	for (var j = 0; j < num_spans; j++) 
		for (var k = 0; k < cur_num_rows; k++)
			repeated_row_labels.push(cur_row_labels[k]);
    table.rowLabels = repeated_row_labels;
}
 
// Reshape the statistics and set them to the table
for (var j = 0; j < stats_array.length; j++) {
	var dummy_stat = table.get(table.statistics[0]);
	var stat = stats_array[j];
	for (var row = 0; row < table.numberRows; row++) {
		for (var col = 0; col < table.numberColumns; col++) {
			var r = row%cur_num_rows;
			var chunk = Math.floor(row/cur_num_rows);
			dummy_stat[row][col] = stat[r][chunk*table.numberColumns + col];
		}
	}
	table.set(table.statistics[j], dummy_stat);
}
 
// Clear results that don't make sense or which are wrong
var forbidden_stats = ["% Column Share", "% Row Share", "% Share", "% Total Responses", "% Column Responses", "% Row Responses", "Index"];
forbidden_stats.forEach(function(stat) { 
	if (table.availableStatistics.indexOf(stat) > 0)
		setStatisticToNaN(stat);
});
 
// Tidy the resulting table
table.clearColumnSpans();
 
// Returns true if the specified question is one-dimensional
function questionInTableIs1D(question_name) {
	var temp_table = calculateTable(question_name, "SUMMARY", ['!UseQFilters'], '!UseQWeight');
	return !temp_table.columnLabels;
}
 
 
// Replace all statistic values in the named statistic with NaN (or blanks for statistics that have string values)
function setStatisticToNaN(statistic_name) {
	var nan_stat = table.get(statistic_name);
	var num_rows = table.numberRows;
	var num_cols = table.numberColumns;
	var nan_value;
	if (statistic_name == "Column Comparisons" || statistic_name == "Columns Compared" || statistic_name == "Column Names")
		nan_value = "";
	else
		nan_value = NaN;
	for (var row = 0; row < num_rows; row++)
		for (var col = 0; col < num_cols; col++)
			nan_stat[row][col] = nan_value;
	table.set(statistic_name, nan_stat);
}

See also

Personal tools
Namespaces

Variants
Actions
Navigation
Categories
Toolbox