Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

How to combine randomize and skip logic

Hi there, I'm trying to create a survey where I'm asking a multi-select, the respondent can select up to nine features they would be interested in. After that, there is a set of price ladder questions for each feature. However, no matter how many the respondent selects, I only want to ask price ladder questions for two of the features they've selected. One additional caveat is that there there are two out of the nine, if the respondent does select them, I do want to test for it, regardless of how many others they've selected.

Currently, I've set up the first multi-select question. For each of the price ladder, I have the BetterLighthouseLibrary and the actual price ladder question for each. I have skip logic so that if the user have already completed up to 2 price ladder questions, they skip to the next set of questions. However, what I can't figure out is how to apply randomize to it.

I have tried applying randomize on a page and by creating a block list and set length to just 2, but for both, I get the error of "Skip Logic - Skipping to a question that is not in the same randomized block as the question being skipped from is not allowed. Change the Skip To question to a question contained in the same block or outside the set range." or "Skip Logic - Skipping to a question that is involved in the same page randomization as the question being skipped from is not allowed."

Any advice would be appreciated. Thanks for your help.
asked Dec 8, 2020 by anonymous

1 Answer

0 votes
 
Best answer
I will try to provide an example to assist here. Hopefully this gets you up and running.

Let's say your multi question is Q1 with the 9 features.

Now create a constructed list and let's call it FeaturesConList. This will use the parent list used at Q1. It will look like this ...
AIC(Q1)
Randomize()
ListMax(2)

This constructed list will tell us which of the 9 features the respondent will answer.

Now you have a set of questions for each of the 9 options. Let's assume they look something like this ...

Feature 1: Q2-Q3
Feature 2: Q4-Q5
Feature 3: Q6-Q7
Feature 4: Q8-Q9
Feature 5: Q10-Q11
Feature 6: Q12-Q13
Feature 7: Q14-Q15
Feature 8: Q16-Q17
Feature 9: Q18-Q19

Now go to Randomize | Blocks | Add Set and enter in each of the 9 blocks (Q2-Q3, Q4-Q5, ..., Q18-Q19). Select FeaturesConList as the constructed list. Hit OK and save. The number of blocks entered should be 9 to match the 9 features.

Now the way this should work, is the respondent selects as many features as necessary at Q1, then your constructed list will randomly select 2 of those features (it could be one feature if they only selected one feature at Q1). You should see only 2 blocks of questions shown maximum to the respondent based on this setup.

Note: No skips required here. The randomised blocks are doing the dirty work for you. Pretty cool hey.

Try it out ...

Let me know how you go.
answered Dec 8, 2020 by Paul Moon Platinum (97,470 points)
Hi Paul, that worked perfectly. I didn't realize that randomized blocks will solve the skip issue, that's great. Thank you!

I did have a quick follow up, as this doesn't allow for the prioritization of certain features . If say, features 1 and 2 were the priority features in the instance that if a user selected 1, 2, 4, and 5, I would always want to prioritize 1 and 2. Or if a user selected only one of the two, say something like 1, 3, 5, and 6, I would want to prioritize the 1 and then randomize the 3, 5, and 6. Is there an way to account for that? Thank you!
Hi Paul, I was able to figure out my question and posting here for posterity.

AIC has the ability to limit the response with this function "AIC (QuestionName, StartMember#, EndMember#)." I've pulled out the prioritized features out of the random loop and apply the skip functions to them, while still retaining the randomize loop you suggested for the rest of the features.

Thanks again for all your help. Thank you!
You can apply priorities within constructed lists.

Example ...

If I wanted to apply a priority to features 1+2, I would do this ...

Constructed list 1 - call it Features1ConList
AIC(Q1,1,2)
Randomize()

Constructed list 2 - call it Features2ConList
AIC(Q1,3,9)
Randomize()

Constructed list 3 - call it FeaturesConList
ADD(Features1ConList)
ADD(Features2ConList)
ListMax(2)
Randomize()

All the randomised block setup remains the same.

And great to hear that you have it working beautifully.

Puts a smile on my face!
Hi Paul,
Will this same logic work if the blocks represent CBC exercises?

I have a study where respondents are pre-selected to go to 2 of 12 conjoints, based on pass-in variables I'm getting from an external software platform for the non-conjoint part of the survey. Let's call them Exercise1 and Exercise2.  

Right now I have branched skip logic to take respondents to each CBC conjoint they're supposed to see. So, if, say, Exercise1=1 and Exercise2=3, they go to Conjoint 1 since they meet the logic for Exercise1=1 or Exercise2=1, and Conjoint 3 is they meet the logic of Exercise1=3 or Exercise2=3.

That works perfectly fine on its own, with the skip logic on conjoint specific pre-screens before the conjoint itself. However, it doesn't randomize the order in which the respondent sees each exercise by itself.

What I want to do is if a respondent is assigned to exercise 1 and exercise 3, for example, sometimes have the conjoint questions for exercise 1 be first, and sometimes have the exercises for exercise 3 be first.

I tried to create randomized sets of each conjoint section, from my initial first screen of text question to the last conjoint question for each set, and it doesn't seem to work when I test it with the existing skip logic patterns. You just keep respondents seeing the conjoints hierarchically according to the redirects of the skip logic to the next coded exercise.

So, what it sounds like what I want to do is:
1) Set up a ParentList of 12 elements

1) Create a constructed list, which I'll creatively calling ConjList. It will represent coding for the two conjoints the respondent sees, using Unverified PERL, with GETVALUE for my passed-in variable and for each code, adding them to a listmember value of ParentList that might put them there as true or false.

So, something like this:

Begin Unverified Perl

if(GETVALUE("Exercise1") == 1 || GETVALUE("Exercise2") == 1)

{

 ADD("ParentList",1)

elseif(GETVALUE("Exercise1") == 2 || GETVALUE("Exercise2") == 2)
{
 ADD("ParentList",2)
}
elseif(GETVALUE("Exercise1") == 3 || GETVALUE("Exercise2") == 3)
{
 ADD("ParentList",3)
}

(and so on, for all 12 conditions)

}

End Unverified

2) Apply this ConjList constructed list to every one of the 12 conjoint blocks I set up in Randomized Blocks
3) Get rid of my skip logic in each individual conjoint, since it's not necessary now.

Sound right?
Does this approach work for conjoint exercises?
Stuart, I think your idea will work. It sounds very similar to the problem I assisted the other person with.

Note that I am no conjoint expert. I leave that topic to Bryan Orme, Keith Chrzan, Aaron Hill, Brian McEwan, etc. Providing you are happy to skip various conjoint exercises and understand all the consequences of doing that, then I'm fine too.

My first point is when using "else if" in Perl, it needs to be specified as "elsif", not "elseif". I know it's a bit odd but that is a rule we need to abide by.

Furthermore, always add a ";" at the end of each ADD command.

I thought I would make your constructed list more efficient / tidy by using a for loop. See below ...
Begin Unverified Perl
 
 my $i=1;
 
 for($i=1; $i<=12; $i++)
  {
   if(VALUE("Exercise1")==$i || VALUE("Exercise2")==$i)
    {
     ADD("ParentList",$i);
    }
  }

 RANDOMIZE();
  
End Unverified

We don't need to use a LISTMAX() here as you only have 2 pass-in fields representing the exercises.

The next step is to insert your 12 blocks. The constructed list to use here will be "ConjList" as you stated.

Then remove all skips associated to the skipping of the conjoint exercises.

The beauty of using a randomised block approach is the constructed list "ConjList" will tell you which conjoint exercises have been answered and in which order (which was 1st and which was 2nd). You can also export this constructed list with all other survey data to assist with analysis.

Hope that helps you out my friend. Take care.
I'll test tomorrow. And thanks for cleaning up my code a little and doing a quick debug on the syntax. You saved me a few minutes there.

Much appreciate, Paul!
...