Modify Cell Content - Remove Decimals Without Rounding
This rule modified the selected statistics to remove the decimal places after a certain number without rounding the numbers. Unlike various rounding procedures this does not change the last decimal place.
Example
In this example, the Average has been selected as the statistic to modify, and the number of decimal places chosen is 1. All decimal places after the first now show zeros. Note that unlike other rounding procedures, this does not change the decimal place that has been kept (that is, the first decimal place).
Technical details
Significance tests are conducted on the results prior to the modification.
You can choose to modify all numeric statistics shown on the table, or you can select a set of statistics to modify.
You can also choose whether or not marginal statistics (Statistics - Below and Statistics - Right) are included in the modification.
A foot note is added to explain which statistics have been modified in this way.
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
includeWeb('Table JavaScript Utility Functions');
// Decimal number control
var decimals_label = form.newLabel("Decimal places to keep: ");
var decimals_box = form.newNumericUpDown("nd");
decimals_box.setDefault(1);
decimals_box.setIncrement(1);
decimals_box.setMinimum(0);
decimals_box.setMaximum(10);
decimals_box.lineBreakAfter = true;
// Apply to marginal statistics?
var marginals_check_box = form.newCheckBox("mcb", "Apply to marginal statistics");
marginals_check_box.lineBreakAfter = true;
marginals_check_box.setDefault(true);
// Apply to all statistics?
var all_stats_box = form.newCheckBox("ascb", "Apply to all statistics");
all_stats_box.lineBreakAfter = true;
includeWeb('Table JavaScript Utility Functions');
// Decimal number control
var decimals_label = form.newLabel("Decimal places to keep: ");
var decimals_box = form.newNumericUpDown("nd");
decimals_box.setDefault(1);
decimals_box.setIncrement(1);
decimals_box.setMinimum(0);
decimals_box.setMaximum(10);
decimals_box.lineBreakAfter = true;
// Apply to marginal statistics?
var marginals_check_box = form.newCheckBox("mcb", "Apply to marginal statistics");
marginals_check_box.lineBreakAfter = true;
marginals_check_box.setDefault(true);
// Apply to all statistics?
var all_stats_box = form.newCheckBox("ascb", "Apply to all statistics");
all_stats_box.lineBreakAfter = true;
var controls = [decimals_label, decimals_box, marginals_check_box, all_stats_box];
form.setInputControls(controls);
var all_stats = all_stats_box.getValue();
var num_decimals = decimals_box.getValue();
var do_marginals = marginals_check_box.getValue();
// List of statistics for the menu. Text-based stats, or stats which are
// already integers (eg Base n) are not included.
var not_selected_string = "(none)";
var stat_list = [not_selected_string].concat(_GLOBAL_STAT_LIST);
var stats_to_remove = ["Base n", "Column n", "Column Comparisons",
"Column Names",
"Columns Compared", "Expected n", "Missing n", "n",
"n Observations", "Not duplicate", "Row n", "Text",
"Text With No Blanks", "Unique Text"];
stat_list = stat_list.filter(function (s) { return stats_to_remove.indexOf(s) == -1; });
var all_selected_stats = table.statistics;
if (do_marginals) {
if (rightTableExists())
all_selected_stats = all_selected_stats.concat(right_table.statistics);
if (belowTableExists())
all_selected_stats = all_selected_stats.concat(below_table.statistics);
}
// If not applying to all stats then get the user to select which stats to use
var stats = [];
if (!all_stats) {
var stat_list_translated = translateStats(stat_list);
var stat_select_label = form.newLabel("Apply only to:");
stat_select_label.lineBreakAfter = true;
controls.push(stat_select_label);
var counter = 0;
var new_stat_box, last_selection;
var make_new_stat_box = function () {
new_stat_box = form.newComboBox("sb" + counter, stat_list_translated);
new_stat_box.setDefault(not_selected_string);
new_stat_box.lineBreakAfter = true;
controls.push(new_stat_box);
form.setInputControls(controls);
last_selection = new_stat_box.getValue();
};
make_new_stat_box();
while (last_selection != not_selected_string) {
stats.push(last_selection);
counter ++;
make_new_stat_box();
}
var translated_stats = stats;
stats = untranslateStats(stats,stat_list_translated,stat_list);
} else {
stats = all_selected_stats;
// var translated_stats = translateStats(stats); // not needed if all_stats is True
}
// Create messages to use in summary and footer
var decimals_string = num_decimals + " decimal place" + (num_decimals == 1 ? "" : "s");
var summary_text = "Remove decimals (without rounding) after " + decimals_string + ": "
+ (all_stats ? "all statistics" : translated_stats.slice(0, Math.min(3, stats.length)).join(", ") + (stats.length > 3 ? "..." : ""));
form.setSummary(summary_text);
form.setHeading("Remove Decimals Without Rounding");
// Change table stats
truncateTable(table, function (stat, truncated_stats) {
table.set(stat, truncated_stats);
});
if (do_marginals) {
if (rightTableExists()) {
truncateTable(right_table, function (stat, truncated_stats) {
setMarginalStatistic(right_table, stat, truncated_stats);
});
}
if (belowTableExists()) {
truncateTable(below_table, function (stat, truncated_stats) {
setMarginalStatistic(below_table, stat, truncated_stats);
});
}
}
// Set footer
var trimmed_stats = stats.filter(function (s) { return all_selected_stats.indexOf(s) > -1 });
if (all_stats || trimmed_stats.length > 0) {
var footer = table.extraFooters;
var footer_message = (all_stats ? "All statistics" : translateStats(trimmed_stats).join(", "))
+ " have decimals removed after " + decimals_string;
footer.push(footer_message);
table.extraFooters = footer;
}
// For each selected statistic, get its values, truncate them, and then
// fire a function that decides how to apply them to the table.
//
// apply_truncated_stats should be a function(stat, 2d_stats_array) {}
function truncateTable(ttable, apply_truncated_stats) {
ttable.statistics.forEach(function (stat) {
if (stats.indexOf(stat) > -1) {
var current_values = ttable.get(stat);
if (typeof current_values[0][0] != "string") {
apply_truncated_stats(stat, truncateStats(current_values, num_decimals));
}
}
});
}
// Truncate the number to a certain number of decimal places
// by converting the number to a string, cutting the number
// of decimals, then converting back to a float.
function truncateDecimalNumber(x, num_decimals) {
if (isNaN(x) || x == 0)
return x;
var num_string = x.toPrecision(13); // Q rounds the raw numbers to 13 decimal places
var split_string = num_string.split(".");
var new_string = split_string[0] + "." + split_string[1].substr(0, num_decimals);
return parseFloat(new_string);
}
// Truncate the whole array of stats. array should be in the shape of a Q table.
function truncateStats(array, num_decimals) {
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) {
return truncateDecimalNumber(b, num_decimals);
});
});
return new_values;
}
// convert English names of statistics to their translation safely
function translateStats(stats) {
return stats.map(function(s) {
try {
return table.getTranslation(s);
}catch(e) {
return s;
}
});
}
// map translated statistics back to their English/Q name
function untranslateStats(stats, all_translated_stats,all_stats_eng) {
return stats.map(function(s) { return all_stats_eng[all_translated_stats.indexOf(s)]; });
}
See also
- User Input for Rules for technical information on Rules.
- Rule Online Library for other examples of Rules.
- Table JavaScript and Plot JavaScript for the JavaScript that is used to write custom rules.
- JavaScript for information about the JavaScript programming language.
Q Technical Reference
Q Technical Reference
Q Technical Reference > Creating And Modifying Tables
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 > Table JavaScript and Plot JavaScript
Rule Online Library