QScript Sentiment Analysis Functions

From Q
Jump to navigation Jump to search
This page is currently under construction, or it refers to features which are under development and not yet available for use.
This page is under construction. Its contents are only visible to developers!
includeWeb("QScript Functions to Generate Outputs");
includeWeb("QScript R Output Functions");
includeWeb("QScript Selection Functions");
includeWeb("QScript Utility Functions");

function saveSentimentScores() {
    function getBestTextSelection() {
        // Selection
        // - A WordBag output
        // - A Text Question in Data Sources
        // - A Table with a Text question in the rows (comes for free in selected_questions)

        const bad_selection_message = "Select either a table with text data, "
            + "a Text variable, or an item that has been created using Text Analysis > Setup Text Analysis.";
        const user_selections = getAllUserSelections();
        const selected_r_items = user_selections.selected_r_outputs;
        const selected_questions = user_selections.selected_questions;
        const selected_text_questions = selected_questions.filter(function (q) { return q.questionType == "Text"; });
        const selected_primary_text = user_selections.questions_in_rows_of_selected_tables.filter(function (q) { return q.questionType == "Text"; });

        // Can't operate on multiple R outputs.
        if (selected_r_items.length > 1) {
            log("Too many outputs selected. " + bad_selection_message);
            return null;
        }

        // If one output selected, make sure it is
        // calculated, then make sure it has the right class
        if (selected_r_items.length == 1) {
            if (!checkROutputIsValid(selected_r_items[0]))
                return null;
            if (!selected_r_items[0].outputClasses || selected_r_items[0].outputClasses.indexOf("wordBag") == -1) {
                log(bad_selection_message);
                return null;
            }
            return selected_r_items[0];
        }

        if (selected_text_questions.length > 1) {
            log(correctTerminology("Too many questions selected. ") + bad_selection_message);
            return null;
        }

        if (selected_text_questions.length == 1)
            return selected_text_questions[0];

        if (selected_primary_text.length > 1) {
            log("Too many tables selected. " + bad_selection_message);
            return null;
        }

        if (selected_primary_text.length == 1) {
            return selected_primary_text[0];
        }

        log(bad_selection_message);
        return null;
    }

    const selected_object = getBestTextSelection();
    if (selected_object == null)
        return;

    // Figure out the source question so we can put the new
    // variable below it, and to disambiguate in the case of
    // multiple data files.
    let source_question;
    const selected_type = selected_object.type;
    if (selected_type == "Question")
        source_question = selected_object;
    else {
        source_question = selected_object.getInput("formtextvar");
    }

    // Figure out the right data file to add to (if more than one)
    let target_data_file = project.dataFiles[0];
    if (project.dataFiles.length > 0) {
        target_data_file = source_question.dataFile;
    }

    const input_string = selected_type == "Question"
        ? generateDisambiguatedVariableName(selected_object.variables[0])
        : stringToRName(selected_object.referenceName);
    const r_expression = "library(flipTextAnalysis)\r\n"
        + "sentiment.scores = SaveNetSentimentScores(" + input_string
        + ", check.simple.suffixes = TRUE, blanks.as.missing = TRUE)";

    const new_q_name = preventDuplicateQuestionName(target_data_file, "Sentiment scores from " + selected_object.name);
    let new_var_name = selected_type == "Question"
        ? selected_object.variables[0].name
        : selected_object.name;
    new_var_name = cleanVariableName(new_var_name);
    new_var_name = preventDuplicateVariableName(target_data_file, new_var_name + "_sentiment");
    let new_var;
    try {
        new_var = target_data_file.newRVariable(r_expression, new_var_name, new_q_name, null);
    }
    catch (e) {
        log("Sentiment scores could not be created from this item: " + e);
        return false;
    }
    const new_question = new_var.question;

    // Move the new variable below its input
    target_data_file.moveAfter([new_var], source_question.variables[0]);
    insertAtHoverButtonIfShown(new_question);
    // Generating outputs
    if (!inDisplayr()) {
        const new_group = generateGroupOfSummaryTables(new_q_name, [new_question]);
        if (new_group && new_group.subItems) {
            project.report.setSelectedRaw([new_group.subItems[0]]);
        }
    }

    return true;
}