javascriptarraysqualtrics

Qualtrics conjoint experiment Javascript randomization condition


I am building a conjoint experiment in Qualtrics with JavaScript about vote choice and democratic norm violations. In a typical conjoint you let all attribute levels be random. However, this is, not realistic in the case of an election since there is only one candidate from each party.

Here is the code I am using right now:

    // Set number of choices (number of elections);
    var CJ_numChoice = 3;

    // Vectors containing all attribute levels:
    var CJ_eth = ["White", "South Asian", "East Asian", "Indigenous"];
    var CJ_gender = ["Man", "Woman"];
    var CJ_age = ["35", "65"];
    var CJ_pid = ["Liberal", "Conservative", "NDP"];
    var CJ_occup = ["Lawyer", "Political Staffer", "Construction worker", "Business person"];
    var CJ_exp = ["No experience", "Mayor", "Member of provincial legislature", "Member of Parliament"];
    var CJ_wel = ["Spending on welfare should be kept the same", "Spending on welfare should be increased", "Spending on welfare should be reduced"];
    var CJ_enviro = ["Must find a balance between reducing greenhouse gas emissions and maintaining jobs in the oil and gas sector", "Must prioritize reducing greenhouse gas emissions over the jobs in the oil and gas sector", "Must prioritize jobs in the oil and gas sector over reducing greenhouse gas emissions"];
    var CJ_court = ["A prime minister should always adhere to court decisions even though they might seem politicized", "A prime minister should not be bound by court decisions he or she regards as politicized"];
    var CJ_prot = ["The prime minister should not be allowed to ban non-violent opposition protests under any circumstances", "The prime minister should be free to ban non-violent opposition protests if they are disruptive to society"];

    // Fisher - Yates shuffle:
    function shuffle(array) {
        for (var i = array.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
        return array;
    }

    // Shuffle a vector, choose the first entry:
    function shuffle_one(theArray) {
        var out = shuffle(theArray);
        return out[0];
    }

    var CJ_attribnames = ["Ethnicity", "Gender", "Age", "Party", "Previous occupation", "Prior political experience", "Position on welfare spending", "Position on environmental issues", "Position on courts", "Position on press freedom", "Position on protests rights"];

    function randomize(i) {
        // Randomly draw the attributes for each candidate
        var c1 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), shuffle_one(CJ_pid), shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];
        var c2 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), shuffle_one(CJ_pid), shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];

        
        
        // Save the results
        for (var k = 1; k <= CJ_attribnames.length; k++) {
            var CJ_index = k - 1;
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_name', CJ_attribnames[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c1', c1[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c2', c2[CJ_index]);
        }
    }

    for (var i = 1; i <= CJ_numChoice; i++) {
        randomize(i);
    }
});

Can you help me figure out how to make sure that both candidate parties are always different in the following style: Make candidate 1's party be random. If candidate 1 is Liberal or NDP Candidate 2 can only be Conservative. if Candidate 1 is Conservative, candidate 2 can randomly be Liberal or NDP.


Solution

  • You have to modify the code a little. The simplest solution would be to add an if statement within an infinite loop in the randomize() function, check if the parties are different, and if they are, break out of the loop.

    function randomize(i) {
        var c1 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), shuffle_one(CJ_pid), shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];
    
    
        var c2 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), shuffle_one(CJ_pid), shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];
    
    
    
        while (true) {
            if (c2[3] !== c1[3]) {
                break;
            }
            
            c2[3] = shuffle_one(CJ_pid);
        } 
    
        // Save the results
        for (var k = 1; k <= CJ_attribnames.length; k++) {
            var CJ_index = k - 1;
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_name', CJ_attribnames[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c1', c1[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c2', c2[CJ_index]);
        }
    }
    
    

    Modifications done to your code here are these:

    1. I have added a while loop that runs infinite times
    2. Checks if the party of c2 is the same as the party of c1
    3. Breaks out of the loop if the parties are different
    4. If the parties are the same, randomly, another party will be chosen, and the loop will be repeated.

    The above solution picks both parties at random.


    EDIT

    If you want to assign a party for c2 based on which party c1 belongs to, you can do the following

    function randomize(i) {
        var c1 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), shuffle_one(CJ_pid), shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];
    
    
        var c2 = [shuffle_one(CJ_eth), shuffle_one(CJ_gender), shuffle_one(CJ_age), '', shuffle_one(CJ_occup), shuffle_one(CJ_exp), shuffle_one(CJ_wel), shuffle_one(CJ_enviro), shuffle_one(CJ_court), shuffle_one(CJ_prot)];
    
    
        // Ensure a different party for candidate 2 based on partyC1
        if (c1[3] === 'Liberal' || c1[3] === 'NDP') {
            c2[3] = 'Conservative';
        } else if (partyC1 === 'Conservative') {
            c2[3] = Math.random() < 0.5 ? 'Liberal' : 'NDP';
        }
    
    
        // Save the results
        for (var k = 1; k <= CJ_attribnames.length; k++) {
            var CJ_index = k - 1;
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_name', CJ_attribnames[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c1', c1[CJ_index]);
            Qualtrics.SurveyEngine.setEmbeddedData('c' + i + '_attrib' + k + '_c2', c2[CJ_index]);
        }
    }
    

    Modifications done:

    1. Create c1 as usual, create c2 with an empty party
    2. Use an if statement to check the party if c1
    3. if c1 belongs to Liberal or NDP, assign c2 as Conservative. if c1 is conservative, randomly pick Liberal or NDP