Modify Cell Content - Round Data

From Q
Jump to navigation Jump to search


This rule modifies the selected statistics to round the data to a specified number of decimal places, for use when exporting results (e.g., to Excel). This rule does not modify the number of decimal places that appear in Q (see Formatting Cells for instructions for modifying the number of decimals in Q).

Example

In this example, the data has been rounded to 0 decimal places.

RoundingValues.png

Technical details

  • This rule rounds to the nearest multiple of 10. For example, with no decimal places, it rounds to the nearest integer.
  • From time-to-time you may experience inconsistent results due to the influence that your operating system settings and your computer's process have on rounding.
  • 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 footnote 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'); 

form.setHeading("Round Data");
let description = form.newLabel("Apply rounding to the cells in the table");
description.lineBreakAfter = true;
 
// Decimal number control
let decimals_label = form.newLabel("Decimal places to round: ");
let 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?
let marginals_check_box = form.newCheckBox("mcb", "Apply to marginal statistics");
marginals_check_box.lineBreakAfter = true;
marginals_check_box.setDefault(true);
 
// Apply to all statistics?
let all_stats_box = form.newCheckBox("ascb", "Apply to all statistics");
all_stats_box.lineBreakAfter = true;

 
let controls = [description, decimals_label, decimals_box, marginals_check_box, all_stats_box];
form.setInputControls(controls);
 
let all_stats = all_stats_box.getValue(); 
let num_decimals = decimals_box.getValue();
let 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.
let not_selected_string = "(none)";
let stat_list = [not_selected_string].concat(table.availableStatistics);


let stats_to_remove =  ["Base n", "Column n", 
                        "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 && !isTextStatistic(s); 
});


let 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
let stats = [];
let translated_stats;
if (!all_stats) {
    let stat_list_translated = translateStats(stat_list);
    let stat_select_label = form.newLabel("Apply only to:");
    stat_select_label.lineBreakAfter = true;
    controls.push(stat_select_label);
    let counter = 0;
    let new_stat_box, last_selection;

    let 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();
    }
    translated_stats = stats;
    stats = untranslateStats(stats,stat_list_translated,stat_list);    
} else
    stats = all_selected_stats;
 
 
// Create messages to use in summary and footer 
let decimals_string = num_decimals + " decimal place" + (num_decimals == 1 ? "" : "s");
let summary_text = "Round to " + 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("Round");
 
// Change table stats

roundTable(table, function (stat, round_stats) {
    table.set(stat, round_stats);
});

if (do_marginals) {
    if (rightTableExists()) {
        roundTable(right_table, function (stat, round_stats) {
            setMarginalStatistic(right_table, stat, round_stats);
        });
    }
    if (belowTableExists()) {
        roundTable(below_table, function (stat, round_stats) {
            setMarginalStatistic(below_table, stat, round_stats);
        });
    }
}

// Set footer
if (!isRTable()) {
    let trimmed_stats = stats.filter(function (s) { return all_selected_stats.indexOf(s) > -1 });
    if (all_stats || trimmed_stats.length > 0) {
        let footer = table.extraFooters;
        let footer_message = (all_stats ? "All statistics" : translateStats(trimmed_stats).join(", ")) 
                            + (all_stats || trimmed_stats.length > 1 ? " have " : " has ")
                            + "been rounded to " + decimals_string;
        footer.push(footer_message);
        table.extraFooters = footer;
    }
}

// For each selected statistic, get its values, round them, and then
// fire a function that decides how to apply them to the table.
//
// apply_round_stats should be a function(stat, 2d_stats_array) {}
function roundTable(ttable, apply_round_stats) {
    ttable.statistics.forEach(function (stat) {
        if (stats.indexOf(stat) > -1) {
            let current_values = ttable.get(stat);
            if (typeof current_values[0][0] != "string") {
                apply_round_stats(stat, roundStats(current_values, num_decimals));
            }
        }
    });    
}

See also