This rule requires Q version 5.2 or later. If you do not have this version, contact support@q-researchsoftware.com to inquire about an upgrade.
This rule uses a number of tricks to move the numbers around in the table, and as a result there are some limitations to be aware of:
includeWeb('Table JavaScript Utility Functions');
includeWeb('JavaScript Utilities');
form.setSummary("Show Statistics Above");
if (Q.fileFormatVersion() <= 10.9) {
alert("Show Statistics Above requires Q version 5.2 or later. For access, contact support@q-researchsoftware.com");
form.ruleNotApplicable("it requires an upcoming version of Q");
}
table.requireOriginalRowsColumns();
if (!belowTableExists())
form.ruleNotApplicable("this table does not have Statistics - Below");
var not_selected_string = "(none)";
var _GLOBAL_STAT_BELOW_LIST = ["Average",
"Sum",
"Column n",
"Column Population",
"Base n",
"Base Population",
"Column Comparisons",
"Column Names",
"Columns Compared",
"5th Percentile",
"25th Percentile",
"75th Percentile",
"95th Percentile",
"Column Standard Error",
"Corrected p",
"Correlation",
"Cumulative %",
"d.f.",
"Effective n",
"Effective Base n",
"Expected Correlation",
"Interquartile Range",
"Lower Confidence Interval",
"Maximum",
"Median",
"Minimum",
"Missing n",
"Mode",
"Multiple Comparison Adjustment",
"p",
"Standard Deviation",
"Standard Error",
"Trimmed Average",
"Upper Confidence Interval",
"z-Statistic"];
table.showMissingAs("");
// Controls for shading the cells of the new rows
var shade_stats_checkbox = form.newCheckBox("doShade", "Shade rows");
shade_stats_checkbox.setDefault(false);
shade_stats_checkbox.lineBreakAfter = true;
var form_controls = [shade_stats_checkbox];
form.setInputControls(form_controls);
if (shade_stats_checkbox.getValue()) {
var primary_color_label = form.newLabel("Primary color");
var primary_shade_color_picker = form.newColorPicker("primary");
//primary_shade_color_picker.lineBreakAfter = true;
primary_shade_color_picker.setDefault([235, 235, 235]);
var secondary_color_label = form.newLabel("Secondary color");
var secondary_shade_color_picker = form.newColorPicker("secondary");
secondary_shade_color_picker.lineBreakAfter = true;
secondary_shade_color_picker.setDefault([245, 245, 245]);
form_controls = form_controls.concat([primary_color_label,primary_shade_color_picker, secondary_color_label, secondary_shade_color_picker]);
form.setInputControls(form_controls);
}
// Controls for allowing the user to rename statistics
var do_renaming_box = form.newCheckBox("formRename", "Rename statistics");
do_renaming_box.setDefault(false);
do_renaming_box.lineBreakAfter = true;
form_controls.push(do_renaming_box);
form.setInputControls(form_controls);
var rename_obj = [];
if (do_renaming_box.getValue()) {
var counter = 0;
var remaining_stats = _GLOBAL_STAT_BELOW_LIST.slice();
var translated_stats = translateStats(remaining_stats);
var stat_label = form.newLabel("Statistic");
var stat_box = form.newComboBox("sb"+counter.toString(),
[not_selected_string].concat(translated_stats))
stat_box.setDefault(not_selected_string);
var name_label = form.newLabel("New name");
var name_box = form.newTextBox("nb"+counter.toString());
name_box.lineBreakAfter = true;
form_controls = form_controls.concat([stat_label,
stat_box,
name_label,
name_box]);
form.setInputControls(form_controls);
var selected_translated = stat_box.getValue();
var position, last_selected_stat;
//alert(last_selected_stat != not_selected_string);
while (selected_translated != not_selected_string) {
position = translated_stats.indexOf(selected_translated);
last_selected_stat = remaining_stats[position];
rename_obj.push({stat: last_selected_stat, name: name_box.getValue()});
counter++;
remaining_stats.splice(position, 1);
translated_stats.splice(position,1);
//alert("sb"+counter.toString());
var stat_box = form.newComboBox("sb"+counter.toString(),
[not_selected_string].concat(translated_stats));
stat_box.setDefault(not_selected_string);
var name_box = form.newTextBox("nb"+counter.toString());
name_box.lineBreakAfter = true;
form_controls = form_controls.concat([stat_label,
stat_box,
name_label,
name_box]);
form.setInputControls(form_controls);
selected_translated = stat_box.getValue();
//alert(last_selected_stat != not_selected_string);
}
}
var sample_size_box = form.newCheckBox("formAlways",
"Always show sample size " +
"(whichever is appropriate for each table)");
sample_size_box.setDefault(false);
sample_size_box.lineBreakAfter = true;
form_controls.push(sample_size_box);
form.setInputControls(form_controls);
// Controls for manually selecting which statistics get moved to the top
var choose_stats_box = form.newCheckBox("formDoAll", "Choose statistics to place at top");
choose_stats_box.setDefault(false);
choose_stats_box.lineBreakAfter = true;
form_controls.push(choose_stats_box);
form.setInputControls(form_controls);
var stats_to_show = [];
if (choose_stats_box.getValue()) {
var counter = 0;
var remaining_stats = _GLOBAL_STAT_BELOW_LIST.slice();
var translated_stats = translateStats(remaining_stats);
var selected_stat_label = form.newLabel("Show at the top:");
selected_stat_label.lineBreakAfter = true;
var show_stat_box = form.newComboBox("ssb" + counter,
[not_selected_string].concat(translated_stats));
show_stat_box.lineBreakAfter = true;
show_stat_box.setDefault(not_selected_string);
form_controls = form_controls.concat([selected_stat_label, show_stat_box]);
form.setInputControls(form_controls);
var selected_translated = show_stat_box.getValue();
var selected_stat;
while (selected_translated != not_selected_string) {
position = translated_stats.indexOf(selected_translated);
selected_stat = remaining_stats[position];
stats_to_show.push(selected_stat);
remaining_stats.splice(position,1);
translated_stats.splice(position,1);
counter ++;
var show_stat_box = form.newComboBox("ssb" + counter,
[not_selected_string].concat(translated_stats));
show_stat_box.lineBreakAfter = true;
show_stat_box.setDefault(not_selected_string);
form_controls.push(show_stat_box);
form.setInputControls(form_controls);
selected_translated = show_stat_box.getValue();
}
stats_to_show = intersection(stats_to_show, below_table.availableStatistics);
stats_to_show.reverse();
} else
stats_to_show = below_table.statistics;
// Work out the appropriate sample size stat for this table and add it to the list of stats if not there already
if (sample_size_box.getValue()) {
// Checking to see where column n is available
var use_column_n = false;
var use_base_n = false;
var blue_type = table.blueQuestion.questionType;
var blue_numeric_1d = blue_type == "Number" || blue_type == "Number - Multi";
var brown_type = table.brownQuestion.questionType;
var brown_numeric_1d = brown_type == "Number" || brown_type == "Number - Multi" ;
if ((blue_type == "Number - Grid" || blue_type == "Pick Any - Grid") && table.brownQuestion == "SUMMARY")
use_base_n = true;
else if (blue_numeric_1d && !brown_numeric_1d)
use_column_n = true;
else {
use_column_n = below_table.availableStatistics.indexOf('Column n') != -1;
}
if (use_column_n && stats_to_show.indexOf("Column n") == -1)
stats_to_show.splice(0, 0, "Column n");
if (use_base_n && stats_to_show.indexOf("Base n") == -1)
stats_to_show.splice(0, 0, "Base n");
}
// Add rows to the top of the table
stats_to_show.forEach(function (stat) {
var name_to_use = table.getTranslation(stat);
if (do_renaming_box.getValue()) {
var renamed = rename_obj.filter(function (obj) { return obj.stat == stat; });
if (renamed.length > 0)
name_to_use = renamed[0].name;
}
table.insertRowAfter(null, name_to_use);
});
// Color cells for new rows
if (shade_stats_checkbox.getValue()) {
var cell_colors = table.cellColors;
var selected_primary_color = primary_shade_color_picker.getValue();
var primary_color_row = cell_colors[0].map(function (x) { return selected_primary_color; });
var selected_secondary_color = secondary_shade_color_picker.getValue();
var secondary_color_row = cell_colors[0].map(function (x) { return selected_secondary_color; });
stats_to_show.forEach(function (stat, ind) {
if (ind % 2 == 0)
cell_colors[ind] = primary_color_row;
else
cell_colors[ind] = secondary_color_row;
});
table.cellColors = cell_colors;
}
// Copy values as cell text
// Copy significance highlighting too
var cell_text = table.cellText;
var cell_fonts = table.cellFontColors;
var cell_arrows = table.cellArrows;
var cell_significance = table.cellSignificance;
var below_fonts = below_table.cellFontColors;
var below_arrows = below_table.cellArrows;
var below_significance = below_table.cellSignificance;
if (below_fonts[0].length == 1) {
below_fonts = below_fonts.map(function (x) { return x[0]});
below_arrows = below_arrows.map(function (x) { return x[0]});
below_significance = below_significance.map(function (x) { return x[0]});
} else {
below_fonts = below_fonts[0];
below_arrows = below_arrows[0];
below_significance = below_significance[0];
}
stats_to_show.forEach(function (stat, ind) {
var new_row_ind = stats_to_show.length - ind - 1;
var values = below_table.get(stat);
if (values[0].length == 1)
values = [values.map(function (x) { return x[0]; })];
var translation = getStatisticTranslationString(stat);
var digits = table.decimalPlaces[stat == table.getTranslation(stat) ? stat : translation];
if (_COLUMN_COMPARISON_STATS.indexOf(stat) == -1)
values = formatValues(values, digits, table.showPercentSign && _PERCENT_STATS.indexOf(stat) > -1);
values = values[0].map(function (x) { return [x]; });
cell_text[new_row_ind] = values;
if (_HIGHLIGHTED_BELOW_STATS.indexOf(stat) > -1) {
cell_fonts[new_row_ind] = below_fonts;
cell_arrows[new_row_ind] = below_arrows;
cell_significance[new_row_ind] = below_significance;
}
});
table.cellFontColors = cell_fonts;
table.cellArrows = cell_arrows;
table.cellSignificance = cell_significance;
// Handle % Signs for main table cells. This allows us to turn off the % signs globally and
// then add them in where appropriate.
if (table.showPercentSign) {
table.showPercentSign = false;
var percent_text = table.statistics.map(function (stat) { return _PERCENT_STATS.indexOf(stat) == -1 ? "" : "%"; } );
for (var row = stats_to_show.length; row < table.numberRows; row++) {
for (var col = 0; col < table.numberColumns; col++) {
cell_text[row][col] = percent_text;
}
}
}
// Place new text-based values
table.cellText = cell_text;
// Turn off stats below
if (!choose_stats_box.getValue())
below_table.statistics = [];
else {
below_table.statistics = difference(below_table.statistics, stats_to_show)
// Set translations for any below stats the user requested be renamed but
// not selected to be shown above
if (do_renaming_box.getValue() && below_table.statistics.length > 0) {
var rename_below = rename_obj.filter(function(o) { return below_table.statistics.includes(o.stat); });
for (var i = 0; i < rename_below.length; i++)
form.setTranslation(rename_below[i].stat,rename_below[i].name);
}
}
function formatValues(array, num_decimals, add_percent) {
includeWeb('JavaScript Utilities');
if (num_decimals !== parseInt(num_decimals, 10))
throw new Error("Expected an integer value.");
if (num_decimals < 0)
throw new Error("Expected a non-negative value.");
var new_values = array.map(function (a) {
return a.map(function (b) {
if (isNaN(b))
return "";
var rounded_value = roundDecimalNumber(b, num_decimals);
rounded_value = rounded_value.toString();
if (num_decimals > 0 && rounded_value.indexOf(".") == -1) { //Rounding has removed the decimal places
rounded_value = rounded_value + ".";
for (var j = 0; j < num_decimals; j++)
rounded_value = rounded_value + "0";
}
if (add_percent)
rounded_value = rounded_value + "%";
return rounded_value;
});
});
return new_values;
}
function translateStats(stats) {
return stats.map(function(s) {
try {
return table.getTranslation(s);
}catch(e) {
return s;
}
});
}