Have an idea?

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

Choosing a quota based on which quota has more interviews left

Hi,

I have a survey that has a couple of quotas. During the survey a respondent can be included in both, one, or none of the quotas. I can have sawtooth randomly select one of the quotas if the respondent qualifies for both, but can i select the quota based on which one has more interviews to go?

If so, how can this be achieved?

Thanks.
asked Aug 14, 2015 by cdaniel (405 points)

2 Answers

0 votes
Sorry, unfortunately we don't have the ability to do an explicit "choose least full" option.  When you set a quota to check for cell membership: Randomize All there is some weighting that goes on behind the scenes to make it more likely we check emptier cells to more empty they are, but it's not a true check least full option.
answered Aug 14, 2015 by Brian McEwan Gold Sawtooth Software, Inc. (37,085 points)
Brian, am I correct in saying we can use the quota functions to review all quota cells and how many to go in each (e.g. QuotaCellRemaining). Using this information, we can use a number of methods like Perl in a constructed list or using SetValue to determine the best quota cell and then base the quotas off the constructed list or the variable we defined using SetValue.
Yep, you can definitely do that, though I would probably consider it quite advanced programming.  You basically need to implement a 2-stage process where you first decide what quotas they qualify for, and then you consider the fill of each applicable quota to choose the one you want to assign them to.
Yes, agree. I have used it in the past. Thanks Brian.
Hi,

Is there any chance you could exemplify this method?

Thanks.
Paul would have to help with that, I don't think I'm smart enough to write the code to do that :)
I'm happy to chip in with an example Brian.

I have encountered this issue from time to time with subtle differences applied. I will use this example to assist.

Let's say we had to fill 3 quota cells - red / blue / green. Each cell required 100 completed interviews.

We ask a multiple response select question called Q100 which has 1=Red, 2=Blue and 3=Green. Note the respondent can select multiple answers but we only want the quota that has achieved the minimum count to be incremented.

Create 3 separate quota questions and set their cell limits high (to a value which will never be reached - say 1000). These quota questions are acting like counters and there will be no quota failing happening with them. Let's call them QTRed (Quota value=1 and logic=Q100_1=1), QTBlue (Quota value=1 and logic=Q100_2=1) and QTGreen (Quota value=1 and logic=Q100_3=1).

Create 3 pass-in variables (RedRem, BlueRem, GreenRem) and define them as whole numbers. Pop the SSI Script into the footer of an appropriate question. See below ...
[%SetValue(RedRem,QuotaCellRemaining(QTRed,1))%]
[%SetValue(BlueRem,QuotaCellRemaining(QTBlue,1))%]
[%SetValue(GreenRem,QuotaCellRemaining(QTGreen,1))%]

These variables will store the remaining quota count for each quota cell.

Also create 1 more pass-in variable called QTHigh and define it as whole number. We want to sort the 3 numbers RedRem. BlueRem and GreenRem and save the highest of these in QTHigh. I am using an array to store the numbers which are then sorted. See below ...
[%
Begin Unverified Perl
 
 my @qtcounts=(QUOTACELLREMAINING("QTRed",1),QUOTACELLREMAINING("QTBlue",1),QUOTACELLREMAINING("QTGreen",1));
 my @sortedqtcounts=0;
 my $highestqtcount=0;
  
 @sortedqtcounts=sort{$b<=>$a}@qtcounts;
  
 $highestqtcount=$sortedqtcounts[0];
 
 SETVALUE("QTHigh",$highestqtcount);
  
End Unverified
%]

So now I know the highest number we need to fill. We need to match it up with the quota that requires the most filling. This can be done a number of ways but I popped this Perl Script into a constructed list (call it QuotaList) as such ...
Begin Unverified Perl
 
if (VALUE("RedRem")==VALUE("QTHigh")) 
 {
  ADD("Q100List",1);
 }
 
if (VALUE("BlueRem")==VALUE("QTHigh")) 
 {
  ADD("Q100List",2);
 }
 
if (VALUE("GreenRem")==VALUE("QTHigh")) 
 {
  ADD("Q100List",3);
 }
 
RANDOMIZE();
LISTMAX(1);
  
End Unverified

If equal rankings occur, this list will randomise all equal ranked codes and strip the list down to 1 using ListMax.

This constructed list now stores either a 1=red or 2=blue or 3=green which resembles the minimum achieved quota cell and also caters for equal rankings as mentioned above.

So when you define your quota failure question, use the logic from the constructed list and apply the following in the settings as such ...

1 (Red) -  Value=1 / Cell limit=100 / Logic=ListValue(QuotaList,1)=1
2 (Blue) -  Value=2 / Cell limit=100 / Logic=ListValue(QuotaList,1)=2
3 (Green) -  Value=3 / Cell limit=100 / Logic=ListValue(QuotaList,1)=3

Note - I have had to apply this technique to quotas where the required counts differed so I sorted percentages instead.
0 votes
You can also brute force this using constructed lists. Stealing from Paul's example, let's say once more that you have 3 quotas: Red, Green, and Blue. People can qualify for any of the three based on which colors they chose in a previous question, but should get assigned the the quota with the least number of completes.

Assuming you have a multi-select question called "color" where people select their colors you can build a constructed list called "ColorsChosen" using the Add If Chosen command

AIC(color)


Next you need to find out which quota cells someone qualifies for and which has the least number of completes. If your quota question is called "quota" and has three cells you can build a parent list that lists the number of completes for each cell (let's call it "QuotaCompletes"):

[% QuotaCellCompletes(quota, 1) %]
[% QuotaCellCompletes(quota, 2) %]
[% QuotaCellCompletes(quota, 3) %]


You can then use the mirror command to add all cell complete counts that a respondent will qualify for (because they picked the corresponding color ). Let's call this list "QuotaOrder"

Mirror(ColorChosen)
SortByLabel()


The sort by label command will sort in ascending order so the quota with the lowest number of completes will be at the top of the list.

Our logic for the quota cells can then be something like skip if

ListValue(QuotaOrder, 1) = 1
ListValue(QuotaOrder, 1) = 2
ListValue(QuotaOrder, 1) = 3


for each of the three quota cells and that should do it.
answered Aug 19, 2015 by Jeff Forkner Bronze (2,875 points)
Lovely idea Jeff. And very good use of that handy Mirror function Mike Lodder whipped up. Appreciate you sharing the idea.

And this would work where we required different cell limits for each of the quota definitions. We could convert the quota cells completed into a % at the QuotaCompletes parent list as such ...
[% QuotaCellCompletes(quota, 1) *100/300 %]
[% QuotaCellCompletes(quota, 2) *100/500 %]
[% QuotaCellCompletes(quota, 3) *100/200 %]

Then apply the SortByLabel technique just as you did.

One scenario I can't see you have catered for is equal rankings. How does SortByLabel handle two numbers that are equally ranked? Does it act in the same way as the AddSorted function which neatly randomises equally ranked items? If yes, then you have the problem solved already.

Would love the hear your comments on the SortByLabel function.

Thanks again.
Great question, Paul! From what I have seen in my tests it looks like the SortByLabel() function will just leave things in the default order when you get a tie.

So if quota cell 1 and quota cell 2 both have 20 completes then  quota cell 1 will get left in the first slot.

I have not tested it, but you could probably get around that by randomizing the order on your constructed list before sorting by label.

Mirror(ColorChosen)
Randomize()
SortByLabel()
Thanks for the prompt reply Jeff.

I think the safest play here is to test it and if no randomisation occurs, throw the Randomize() function into the constructed list and you have a perfect solution.

I know the AddSorted function has that beautiful randomisation feature built in for equal rankings. I have tested it out on a number of occasions.

Thanks again for a really neat solution. Pretty cool.
...