Create New Variables - Standardize Data by Case

From Q
Jump to: navigation, search

This QScript standardizes data within respondent.

Technical details

This QScript standardizes data from selected Number - Multi or Pick One - Multi questions, generating a new copy of each. The new standardized data will have an average of 0 for each respondent, and will optionally have a standard deviation of 1 for each respondent. The Sample Standard Deviation is used in this calculation.

This QScript requires Q 4.8 or later

How to apply this QScript

  • Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
  • Click on the QScript when it appears in the QScripts and Rules section of the search results.

OR

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

Customizing the QScript

This QScript is written in JavaScript and can be customized by copying and modifying the JavaScript.

Customizing QScripts in Q4.11 and more recent versions

  • Start typing the name of the QScript into the Search features and data box in the top right of the Q window.
  • Hover your mouse over the QScript when it appears in the QScripts and Rules section of the search results.
  • Press Edit a Copy (bottom-left corner of the preview).
  • Modify the JavaScript (see QScripts for more detail on this).
  • Either:
    • Run the QScript, by pressing the blue triangle button.
    • Save the QScript and run it at a later time, using Automate > Run QScript (Macro) from File.

Customizing QScripts in older versions

  • Copy the JavaScript shown on this page.
  • Create a new text file, giving it a file extension of .QScript. See here for more information about how to do this.
  • Modify the JavaScript (see QScripts for more detail on this).
  • Run the file using Automate > Run QScript (Macro) from File.

JavaScript

// Segmentation - Standardize Data by Case

if (!main())
    log("Qscript cancelled."); 

function main() {
    includeWeb("QScript Functions to Generate Outputs");

    if (!jStat) {
        log("This QScript requires Q 4.8.3 or higher.")
        return false;
    } 
    
    // On the web just take from what is selected.
    var web_mode = (!!Q.isOnTheWeb && Q.isOnTheWeb());
    
    includeWeb('QScript Utility Functions');
    includeWeb('QScript Selection Functions');
    includeWeb('QScript Functions to Generate Outputs');
 
    if (!web_mode) {
        // Get data files
        var selected_datafiles = dataFileSelection();

        // Generate a list of applicable questions along with the highest and lowest category labels
        var relevant_questions = getAllQuestionsByTypes(selected_datafiles, ["Number - Multi", "Pick One - Multi"]);

        if (relevant_questions.length == 0) {
            log("There are no Number - Multi or Pick One - Multi questions in the data file.");
            return false;
        }

        // Prompt user to select questions
        var selected_questions = selectManyQuestions("Which questions would you like to standardize?", relevant_questions).questions;

        if (selected_questions.length == 0) {
            log("No questions selected.");
            return false;
        }

        // Ask about standard deviation adjustment
        var apply_scaling = askYesNo("This script will create a new copy of the questions where each respondent has a mean score of 0." + 
                                     " Would you also like to standardize the data for each respondent to have a standard deviation of 1?");
    }else {
    	var allowed_types = ["Numeric - Multi", "Ordinal - Multi", "Nominal - Multi"];
	    var selected_questions = project.report.selectedQuestions();
        if (selected_questions.length == 0) {
            log("To use this QScript, you must select at least one variable set from Data Sets with one of the following structures: " + allowed_types.join(", "));
            return false;
        }
	    var sorted_selection = splitArrayIntoApplicableAndNotApplicable(selected_questions, function (q) { return allowed_types.indexOf(q.variableSetStructure) != -1 && !q.isBanner; });
	    selected_questions = sorted_selection.applicable;
        if (sorted_selection.notApplicable.length != 0){
            log("The structure for each of the selected variable sets must be one of: " + allowed_types.join(", "));
            return false;
        }    
    
        var apply_scaling = true;
    }
    // Make new questions
    var new_questions = selected_questions.map(function (q) {
        return createNewStandardizedQuestion(q, apply_scaling);
    });
 
    // Add tables to report
    if (!web_mode) {
        generateGroupOfSummaryTables('Standardized Questions', new_questions);
    }else {
        var new_group = project.report.appendGroup();
        new_group.name = "Standardized Variable Sets";
        new_questions.forEach(function (q) {
                var page = new_group.appendPage('Blank');
                page.name = q.name;
                var t = page.appendTable();
                t.primary = q;
        });   
    }
 
    if (!web_mode) {
        log("Tables showing the standardized questions have been added to your report.");
    }else{
        log(makeWordList(new_questions.map(function(q){ return q.name; })) + "'Summary tables have been added to the bottom of your document.");
        // var pages = project.report.subItems;
        // project.report.setSelectedRaw(new_group.subItems[0]]);  // not working atm
    }
    return true;
} 
    
 
// This function uses JavaScript variables to make a standardized copy of the input question.
// The input should be a Number - Multi or a Pick One - Multi
// If apply_scaling is false then the new question will have a mean of zero for each respondent. 
// If apply_scaling is true then the new question will also be scaled to have a standard
// deviation of 1 for each respondent.
function createNewStandardizedQuestion(question, apply_scaling) {
    var web_mode = (!!Q.isOnTheWeb && Q.isOnTheWeb());
    if (!web_mode)
        checkQuestionType(question, ["Number - Multi", "Pick One - Multi"]);
    // else: already checked
    
    var var_name_prefix = "std" + makeid();
    var variables = question.variables;
    var variable_names = variables.map(function(v) { return v.name; });
    var last_var = variables[variables.length-1];
    var num_vars = variable_names.length;
    var data_file = question.dataFile;
    var extra_label = " - Standardized";
 
    // Generate JavaScript Expressions for mean and standard deviation.
    // These are based on Q's ready-made formulas allowing for incomplete data
    var start_expression = "\
var _variables = [" + variable_names.join(", ") + "];\r\n\
var _result;\r\n";
    var core_expression = "\
if (isNaN(_cur_value))\r\n\
    _result = NaN;\r\n\
else {\r\n\
    Q.removeNaNs(_variables);\r\n\
    var _mean = jStat.mean(_variables);\r\n";
 
    // Two different formulas depending on whether the user wants the values scaled by the standard deviation
    var scaling_expression = "\
    var _stdev = jStat.stdev(_variables, true);\r\n\
    if (_stdev < 0.00000001)\r\n\
        _result = 0.0;\r\n\
    else\r\n\
        _result = (_cur_value - _mean) / _stdev;\r\n\
}\r\n\
_result;";
    var no_scaling_expression = "\
    _result = _cur_value - _mean;\r\n\
}\r\n\
_result;";
 
    // Create new JavaScript variables
    var new_vars = [];
    for (var j = 0; j < num_vars; j++) {
        var current_value_expression = "var _cur_value = _variables[" + j + "];\r\n";
        var expression = start_expression + current_value_expression + core_expression;
        if (apply_scaling)
            expression += scaling_expression;
        else 
            expression += no_scaling_expression;
        var new_var = data_file.newJavaScriptVariable(expression, false, var_name_prefix + "_" + (j + 1), variables[j].label, last_var);
        new_vars.push(new_var);
        last_var = new_var;
    }
 
    // Create the new question
    return data_file.setQuestion(preventDuplicateQuestionName(data_file, question.name + extra_label), "Number - Multi", new_vars);
}

Prior to the 15th of December, 2015, this page was known as Segmentation - Standardize Data by Case

See also