QScript Value Attributes Functions

From Q
Jump to: navigation, search

The functions below are designed to help QScripts obtain information from the Value Attributes of a question or variable, or to make changes to the Value Attributes.

For Q's built-in functions for handling the Value Attributes object see QScript ValueAttributes.

To make these functions available when writing a QScript or Rule see JavaScript Reference.

valueAttributesMissingValueIndicatorArray(question)

Given a question, this function looks at all of the unique values, and returns an array that contains either a '0' or a '1' for each unique value, where a '1' indicates that the corresponding value has been set as missing data, and a '0' indicates that the corresponding value has not been set as missing.

valueLabels(question)

Returns an array of the value labels in the input question, where the entries correspond to the unique values for the variable.

numberMissingValues(question)

Returns the number of values in the input question that have been set as Missing Data.

numberScalePoints(q)

Return the number of non-missing values in the input question q.

finalWordInHighestLabel(question)

Returns the last word in the label corresponding to the largest unique value in the input question.

highestLabel(question)

Returns the label that corresponds to the largest unique value in the input question.

getTopOrBottomKNonMissingValues(question, k, is_bottom)(question, k)

Returns an array containing the source values that correspond to the k largest or smallest current values in the input question that have not been set as Missing Data. Source values are returned rather than current values because they can more readily be used to create NETs.

getTopKNonMissingValues(question, k)

Returns an array containing the source values that correspond to the k largest current values in the input question that have not been set as Missing Data. Source values are returned rather than current values because they can more readily be used to create NETs.

getBottomKNonMissingValues(question, k)

Returns an array containing the source values that correspond to the k smallest current values in the input question that have not been set as Missing Data. Source values are returned rather than current values because they can more readily be used to create NETs.

getLabelsForValues(question, value_array)

Given an array of values, returns the an array of the corresponding labels.

getHighestAndLowestValueAndLabel(question)

Returns an object containing the highest and lowest non-missing value and the corresponding label as a string.

For example if the lowest non-missing value is 1, and the corresponding label is "Disagree" and the highest non-missing value is 3, and the corresponding label is "Agree" then this function returns:

  • lowest: "1 Disagree"
  • highest: "3 Agree"

nonMissingValueLabels(question)

Returns an array containing all of the value labels from the input question whose values have not been set as Missing Data.

copyValueAttributesForVariable(from_variable, to_variable)

Copies the value attributes from one variable to another. This example is used in Rebasing Questions Using a Condition.

copyValueAttributesForQuestion(from_question, to_question)

This function copies attributes, variable by variable, from one question to another. This example is used in Rebasing Questions Using a Condition.

setCountThisValueForVariablesInQuestion(question, source_value, count)

If the variables in a question do not share the same unique values, then attempting to set value attributes for the whole question can lead to an exception. This function avoids this problem by setting the value attributes individually for each variable in the question.

setIsMissingDataForVariablesInQuestion(question, source_value, is_missing)

If the variables in a question do not share the same unique values, then attempting to set value attributes for the whole question can lead to an exception. This function avoids this problem by setting the value attributes individually for each variable in the question.

setLabelForVariablesInQuestion(question, source_value, label)

If the variables in a question do not share the same unique values, then attempting to set value attributes for the whole question can lead to an exception. This function avoids this problem by setting the value attributes individually for each variable in the question.

setValueForVariablesInQuestion(question, source_value, value)

If the variables in a question do not share the same unique values, then attempting to set value attributes for the whole question can lead to an exception. This function avoids this problem by setting the value attributes individually for each variable in the question.

valueLabelsContainNumbers(question, min_numbers)

This function returns true if more than min_numbers of the the value labels of the input question contain numbers. This is determined by the function quantify() which checks labels for both digits and English words that refer to numbers.

setHighValuesToMissing(question, max_value)

Sets all values that are greater than or equal to max_value as missing data for the input question.

setLowValuesToMissing(question, min_value)

Sets all values that are less than or equal to min_value as missing data for the input question.

recodeHighValues(question, max_value, new_value)

Recodes all values that are greater than or equal to max_value to new_value for the input question.

recodeLowValues(question, min_value, new_value)

Recodes all values that are less than or equal to min_value to new_value for the input question..

numberOfMissingOrNaNValues(question)

Return the number of unique values in the input question which are either set as Missing Data or have been coded as NaN.

Source Code

// VALUE ATTRIBUTES
 
includeWeb('JavaScript Array Functions');
includeWeb('JavaScript Text Analysis Functions');

// Return an array with length equal to the number of unique
// values in the input question. Each element is either 0 or 1
// with a 1 indicating that the value is set as missing in 
// the value attributes.
function valueAttributesMissingValueIndicatorArray(question) {
    var unique_values = question.uniqueValues;
    var value_attributes = question.valueAttributes;
    return unique_values.map(function(v) { return value_attributes.getIsMissingData(v) ? 1 : 0 });
}
 
// Return an array of value labels from the input question, in the
// order of the unique values.
function valueLabels(question){
    var value_attributes = question.valueAttributes;
    var values = question.uniqueValues;
    return values.map(function(v) { return value_attributes.getLabel(v) });
}
 
// Return the number of values that have been set as missing in the input
// questions.
function numberMissingValues(question) {
    return arraySum(valueAttributesMissingValueIndicatorArray(question));
}

// Count the number of non-missing values in the input question q. 
function numberScalePoints(q) {
    return q.uniqueValues.length - numberMissingValues(q);
}
 
// final word in the highest label
function finalWordInHighestLabel(question) {
    var label = highestLabel(question); //highest value's label
    var split_label = label.split(/[\s,]+/); //using space as a delimiter to turn it into an array
    return split_label[split_label.length - 1]; //last element of the array
}
 
// extracts the label of the highest value
function highestLabel(question) {
    var values = question.uniqueValues;
    return question.valueAttributes.getLabel(values[values.length - 1]);
}
 
 
 
// Get an array of the source values that correspond to the top k current values in the question
// Source values are returned because these can be more readily used to create NETs and
// new variables
function getTopOrBottomKNonMissingValues(question, k, is_bottom, options) {
 
    // Set default legacy options if no options supplied
    if (!options)
        var options = { excludeDK: false };

    var remove_dk = options.excludeDK;

    var attributes = question.valueAttributes;
    var source_values = question.uniqueValues;
    source_values = source_values.filter(function (x) { return !isNaN(attributes.getValue(x)) && !attributes.getIsMissingData(x); });
    
    // Exclude values that correspond to "Don't know" options
    if (remove_dk)
         source_values  = source_values.filter(function (x) { return !isDontKnow(attributes.getLabel(x)); });

 
    if (source_values.length < k)
        throw question.name + " does not have " + k + " non-missing values";
 
    // Sort the source values according the to current values in
    // the value attributes
    if (is_bottom)
        source_values.sort(function(x,y) { return attributes.getValue(x) - attributes.getValue(y)});
    else
        source_values.sort(function(x,y) { return attributes.getValue(y) - attributes.getValue(x)});
 
    var values = source_values.slice(0, k)
 
    return values;
}


 
 
// Get an array of the source values that correspond to the bottom k current values in the question
// Source values are returned because these can be more readily used to create NETs and
// new variables
function getBottomKNonMissingValues(question, k) {
    return getTopOrBottomKNonMissingValues(question, k, true);
}

// Get an array of the source values that correspond to the top k current values in the question
// Source values are returned because these can be more readily used to create NETs and
// new variables
function getTopKNonMissingValues(question, k) {
    return getTopOrBottomKNonMissingValues(question, k, false);
}

// Return an array of labels from the input question that correspond to the specified array of values
function getLabelsForValues(question, value_array) {
    var labels = [];
    var value_attributes = question.valueAttributes;
    var num_vals = value_array.length;
    for (var j = 0; j < num_vals; j++)
        labels.push(value_attributes.getLabel(value_array[j]));
    return labels;
}


// Returns the highest and lowest non-missing value and the corresponding label as a string
// For example if the lowest non-missing value is 1, and the corresponding label is "Disagree"
// and the highest non-missing value is 3, and the corresponding label is "Agree" then this
// function returns:
// - lowest = "1 Disagree"
// - highest = "3 Agree"
function getHighestAndLowestValueAndLabel(question) {
    var attributes = question.valueAttributes;
    var source_values = question.uniqueValues;
    source_values = source_values.filter(function (x) { return !isNaN(attributes.getValue(x)) && !attributes.getIsMissingData(x); });

    // Sort the source values according the to current values in
    // the value attributes
    source_values.sort(function(x,y) { return attributes.getValue(x) - attributes.getValue(y)});

    var low_value = source_values[0];
    var high_value = source_values[source_values.length - 1];

    var highest = attributes.getValue(high_value) + " " + attributes.getLabel(high_value);
    var lowest = attributes.getValue(low_value) + " " + attributes.getLabel(low_value);

    return {highest: highest, lowest: lowest};
}



// Return an array of value labels from the input question whose values are not set as Missing Data in the
function nonMissingValueLabels(question) {
    var missing_value_indicators = valueAttributesMissingValueIndicatorArray(question);
    var non_missing_labels = [];
    var current_unique_values = question.uniqueValues;
    var current_value_attributes = question.valueAttributes;
    var num_vals = current_unique_values.length;
    for (var j = 0; j < num_vals; j++) {
        if (missing_value_indicators[j] == 0)
            non_missing_labels.push(current_value_attributes.getLabel(current_unique_values[j]));
    }
    return non_missing_labels;
}

//Copies the value attributes from one variable to another
function copyValueAttributesForVariable(from_variable, to_variable){
   var n = from_variable.uniqueValues
   var values = from_variable.uniqueValues;
   var qt = to_variable.question.questionType;
   var qt_old = from_variable.question.questionType;
   if (qt != qt_old)
        alert("Question types are different.");
   for (var i=0; i<values.length; i++){
	var v = values[i];
	if (qt != "Text" && qt != "Text - Multi"){
		to_variable.valueAttributes.setLabel(v,from_variable.valueAttributes.getLabel(v));
		to_variable.valueAttributes.setIsMissingData(v,from_variable.valueAttributes.getIsMissingData(v));
		if (qt == "Pick Any" || qt == "Pick Any - Compact" || qt == "Pick Any - Grid")
			to_variable.valueAttributes.setCountThisValue(v,from_variable.valueAttributes.getCountThisValue(v));
		else
			to_variable.valueAttributes.setValue(v,from_variable.valueAttributes.getValue(v));
	 }
    }
}

//This function copies attributes, variable by variable, from one question to another
function copyValueAttributesForQuestion(from_question, to_question){
   var x = from_question.variables;
   var y = to_question.variables;
   if (y.length != x.length)
      alert('Questions contain different numbers of variables.');
   for (var j=0;j<x.length;j++) 
	copyValueAttributesForVariable(x[j], y[j])
}

// The following functions can be used to set the value attributes for each variable
// in a question individually. This is to avoid errors that can arrise when setting
// value attributes for a question, where one of the values does not exist in one
// of the variables.
function setCountThisValueForVariablesInQuestion(question, source_value, count) {
    var variables = question.variables;
    var num_vars = variables.length;
    for (var j = 0; j < num_vars; j++) {
        if (variables[j].uniqueValues.indexOf(source_value) > -1)
            variables[j].valueAttributes.setCountThisValue(source_value, count);
    }
}
function setIsMissingDataForVariablesInQuestion(question, source_value, is_missing) {
    var variables = question.variables;
    var num_vars = variables.length;
    if (isNaN(source_value)) {
        for (var j = 0; j < num_vars; j++) {
            if (isNaN(variables[j].uniqueValues[0]))
                variables[j].valueAttributes.setIsMissingData(source_value, is_missing);
        }
    } else {
        for (var j = 0; j < num_vars; j++) {
            if (variables[j].uniqueValues.indexOf(source_value) > -1)
                variables[j].valueAttributes.setIsMissingData(source_value, is_missing);
        }
    }
}
function setLabelForVariablesInQuestion(question, source_value, label) {
    var variables = question.variables;
    var num_vars = variables.length;
    for (var j = 0; j < num_vars; j++) {
        if (variables[j].uniqueValues.indexOf(source_value) > -1)
            variables[j].valueAttributes.setLabel(source_value, label);
    }
}
function setValueForVariablesInQuestion(question, source_value, value) {
    var variables = question.variables;
    var num_vars = variables.length;
    for (var j = 0; j < num_vars; j++) {
        if (variables[j].uniqueValues.indexOf(source_value) > -1)
            variables[j].valueAttributes.setValue(source_value, value);
    }
}

function valueLabelsContainNumbers(question, min_numbers) {
    var quantified_labels = valueLabels(question).map(quantify);
    var numeric_labels = quantified_labels.filter(function (x) { return !isNaN(x); });
    return numeric_labels.length > min_numbers;
}

function setHighValuesToMissing(question, max_value) {
    var values = question.uniqueValues;
    var num_vals = values.length;
    var attributes = question.valueAttributes;
    for (var j = 0; j < num_vals; j++)
        if (attributes.getValue(values[j]) >= max_value)
            setIsMissingDataForVariablesInQuestion(question, values[j], true);
}

function setLowValuesToMissing(question, min_value) {
    var values = question.uniqueValues;
    var num_vals = values.length;
    var attributes = question.valueAttributes;
    for (var j = 0; j < num_vals; j++)
        if (attributes.getValue(values[j]) <= min_value)
            setIsMissingDataForVariablesInQuestion(question, values[j], true);
}

function recodeHighValues(question, max_value, new_value) {
    var values = question.uniqueValues;
    var num_vals = values.length;
    var attributes = question.valueAttributes;
    for (var j = 0; j < num_vals; j++)
        if (attributes.getValue(values[j]) >= max_value)
            setValueForVariablesInQuestion(question, values[j], new_value);
}

function recodeLowValues(question, min_value, new_value) {
    var values = question.uniqueValues;
    var num_vals = values.length;
    var attributes = question.valueAttributes;
    for (var j = 0; j < num_vals; j++)
        if (attributes.getValue(values[j]) <= min_value)
            setValueForVariablesInQuestion(question, values[j], new_value);
}


// Find the number of unique values which have either been set as
// missing or coded as NaN.
function numberOfMissingOrNaNValues(question) {
    var value_attributes = question.valueAttributes;
    var unique_values = question.uniqueValues;
    var missing_or_nan = unique_values.filter(function (x) { return isNaN(value_attributes.getValue(x)) || value_attributes.getIsMissingData(x); });
    return missing_or_nan.length;
}

See also