Sorting and Reordering - Sort from Highest to Lowest (Does Not Update When Data Changes)

From Q
Jump to: navigation, search

This QScript sorts the questions in the project from highest to lowest (i.e., ranks the data, so that the order of the rows reveals a ranking). This is computed using the entire sample. The order does not update if the data changes (e.g., when filtered or updated). Also, see Sorting and Reordering - Sort Rows (Automatically Updates when Data Changes).

Example

SortingRule.png

Technical details

  • Categories which look like 'Other/Specify', 'Don't Know', 'None of these', or 'All of these' style responses, as well as the NET and SUM rows, will be left at the bottom of the table.
  • This QScript will not try to sort questions that look like scale questions, according to the rules of the function looksLikeScale.
  • Tables are sorted in the descending order of the relevant statistic, as determined by their Question Type:

Technical details

includeWeb('QScript Selection Functions');
includeWeb('QScript Table Functions');
includeWeb('QScript Utility Functions');
includeWeb('QScript Functions to Generate Outputs');
includeWeb('QScript Questionnaire Functions');
includeWeb('QScript Value Attributes Functions');
 
 
function getAllQuestionsFromDataFiles(data_file_array) {
    var selected_questions = [];
    var num_files = data_file_array.length;
    for (var j = 0; j < num_files; j++) {
        selected_questions = selected_questions.concat(data_file_array[j].questions);
    }
    return selected_questions.filter(function(q) { return !q.isHidden && !q.isBanner; }) ;
}
 
 
// This function will sort a Pick One - Multi according to the Row % statistics
// in the right-most column that is not the NET columm
 
// Accounts for the possibility that the data reduction has been transposed
function sortPickOneMultiByRightColumn(question) {
    checkQuestionType(question, ["Pick One - Multi"]);
    var temp_table = project.report.appendTable();
    temp_table.primary = question;
 
    var output;
    try {
        output = temp_table.calculateOutput();
    } catch(e) {
        temp_table.deleteItem();
        return null;// Table is empty
    }
 
    // Handle the case where the table has had its rows and columns swapped
    var values;
    if (output.availableStatistics.indexOf('Row %') > -1) {
        values = getRightMostColumnFromTableExcludingNet(temp_table, 'Row %');
        if (values.filter(function (x) { return !isNaN(x); }).length > 0)
            anchoredDescendingSortTable(temp_table, values, false);
    }
    else {
        values = getBottomRowFromTableExcludingNet(temp_table, 'Column %');
        if (values.filter(function (x) { return !isNaN(x); }).length > 0)
            anchoredDescendingSortTable(temp_table, values, true);
    }
    temp_table.deleteItem();
}
 
function sortGridByLeftColumn(question) {
    checkQuestionType(question, ["Pick Any - Grid", "Number - Grid"]);
    var stat;
    if (question.questionType == "Pick Any - Grid")
        stat = '%';
    else
        stat = 'Average';
    var temp_table = project.report.appendTable();
    temp_table.primary = question;
    var values = getLeftMostColumnFromTableExcludingNet(temp_table, stat);
    if (values.filter(function (x) { return !isNaN(x); }).length > 0)
        anchoredDescendingSortTable(temp_table, values, false);
    temp_table.deleteItem();
}
 
 
 
function anchoredDescendingSortTable(table, values, by_columns) {
    var labels;
    var nets;
    if (!by_columns) {
        labels = table.primary.dataReduction.rowLabels;
        nets = table.primary.dataReduction.netRows;
    } else {
        labels = table.primary.dataReduction.columnLabels;
        nets = table.primary.dataReduction.netColumns;
    }
    if (labels == null)
        alert(table.name + ' has no labels');
    var num_vals = values.length;
 
    for (var i = 0; i < num_vals; i++)  {
        var label = labels[i];
        if (isOther(label))
            values[i] = -999999999995 + i / 100000.0;//adding a small number to break ties
        else if (isNoneOfThese(label))
            values[i] = -999999999996 + i / 100000.0;//adding a small number to break ties;
        else if (isAllOfThese(label))
            values[i] = -999999999997 + i / 100000.0;//adding a small number to break ties;
        else if (isDontKnow(label))
            values[i] = -999999999998 + i / 100000.0;//adding a small number to break ties;
        else if ((nets && nets.indexOf(i) != -1) || (!nets && (label == "NET" || label == "SUM")))
            values[i] = -999999999999 + i / 100000.0;//adding a small number to break ties;
    }
 
    //sorting
    var sorted_values = values.slice(0);
    sorted_values.sort(function (a,b) { return b-a; } );
    var dataReduction = table.primary.dataReduction;
    var n_values = values.length;
    var positions = new Array(values.length);
    var prev_label = null;
    for (var i = 0; i < values.length; i++)  {
        var this_label = labels[values.indexOf(sorted_values[i])];
        dataReduction.moveAfter(this_label,prev_label);
        prev_label = this_label;
    }
 
}
 
 
function getRightMostColumnFromTableExcludingNet(table, stat) {
    var output;
    var values;
    try {
        output = table.calculateOutput();
        values = output.get(stat);
    } catch (e) {
        return null; //This table is empty or does not have the stat
    }
    var num_cols = output.numberColumns;
    var num_rows = output.numberRows;
    var cols_without_net = output.columnIndices(false);
    var result = new Array(num_rows);//as the array could be huge, specifying its size up-front
    if (cols_without_net.length > 0) {
        var col = cols_without_net[cols_without_net.length - 1];
        for (var row = 0; row < num_rows; row ++)
            result[row] = values[row][col] + row / 100000.0;//adding a small number to break ties
    }
    return result;
}
 
function getBottomRowFromTableExcludingNet(table, stat) {
    var output;
    var values;
    try {
        output = table.calculateOutput();
        values = output.get(stat);
    } catch (e) {
        return null; //This table is empty or does not have the stat
    }
    var num_cols = output.numberColumns;
    var num_rows = output.numberRows;
    var rows_without_net = output.rowIndices(false);
    var result = new Array(num_cols);//as the array could be huge, specifying its size up-front
    if (rows_without_net.length > 0) {
        var row = rows_without_net[rows_without_net.length - 1];
        for (var col = 0; col < num_cols; col ++)
            result[col] = values[row][col] + col / 100000.0;//adding a small number to break ties
    }
    return result;
}
 
function getLeftMostColumnFromTableExcludingNet(table, stat) {
    var output;
    var values;
    try {
        output = table.calculateOutput();
        values = output.get(stat);
    } catch (e) {
        return null; //This table is empty or does not have the stat
    }
    var num_cols = output.numberColumns;
    var num_rows = output.numberRows;
    var cols_without_net = output.columnIndices(false);
    var result = new Array(num_rows);//as the array could be huge, specifying its size up-front
    if (cols_without_net.length > 0) {
        var col = cols_without_net[0];
        for (var row = 0; row < num_rows; row ++)
            result[row] = values[row][col] + row / 100000.0;//adding a small number to break ties
    }
    return result;
}
 
function consistentQuestionSort(question) {
    var q_type = question.questionType;
    if (q_type == "Text" || q_type == "Text - Multi")
        return null;
    if (["Pick One", "Pick Any", "Pick Any - Compact", "Number - Multi", "Ranking"].indexOf(q_type) > -1) {
        var temp_table = project.report.appendTable();
        temp_table.primary = question;
        var empty = false;
        try {
            temp_table.calculateOutput()
        } catch (e) {
            empty = true;
        }
        if (!empty)
            sortTableDescending(temp_table);
        temp_table.deleteItem();
    }
    else if (q_type == "Pick One - Multi")
        sortPickOneMultiByRightColumn(question);
    else if (q_type == "Pick Any - Grid" || q_type == "Number - Grid")
        sortGridByLeftColumn(question);  
}
 
// Ask the user to choose which data files to use
var selected_datafiles = dataFileSelection();
 
var candidate_questions = getAllQuestionsFromDataFiles(selected_datafiles).filter(function (q) { return q.questionType != "Text" && q.questionType != "Text - Multi"; } );
var selected_questions = selectManyQuestions("Select questions to sort: ", candidate_questions).questions;
 
selected_questions.forEach(function (question) {
    consistentQuestionSort(question);
});
 
log('QScript finished.');

Prior to the 15th of December, 2015, this page was known as Sort - Sort from Highest to Lowest (Does Not Update When Data Changes)

See also