Re-pending the originally pended least-full cells
This topic shows how you can reuse the cells that were pended as least full in the original interview. The code is suitable for interviews that are restarted from sample management, where the interviewing program replays the interview from the case data, and for snapbacks where the respondent does not change the answers to the quota controlled question so that none of the pended answers are present in the new answer. The procedure for restarts and snapbacks is as follows:
▪Terminate interviews if all the originally pended cells are full.
▪Repend the cells that were originally pended if they are still open.
▪If some cells are now full, pend only the unfilled cells even if this means that fewer cells are pended.
▪Ignore any brands that were mentioned but not pended in the original portion of the interview.
▪Reset the value of the filter question so that later questions are re-asked about the cells that are pended in the restarted portion of the interview.
You'll find some worked examples that clarify these points later in the topic.
The script asks respondents which brands of ice cream they buy and then, for the two brands whose quotas are least full, asks which is the favorite flavor in each brand. The number of cells to pend (two) is set in the QUOTA_Matrix table. The metadata for the example is:
Brands define
{
Alpine,
HelenB "Helen Bradley's",
DFresh "Dairy Fresh",
Kentish "Kentish Farm",
Finborough,
Alsace
};
IceCream "Which brands of ice cream do you buy?" categorical [1..]
{use Brands};
PendedBrands "" categorical [1..]
{use Brands};
FlavorGrid "Which are your favorite flavors in the following brands
of ice cream?" loop
{use Brands} fields
(
Flavor "" categorical [1..1]
{
Chocolate, Mint,
Toffee "Toffee crunch",
Raspberry "Raspberry ripple",
Strawberry "Strawberry",
Vanilla "Vanilla",
OtherFlavor "Other"
};
) column expand grid;
AllFull "All our interviewing targets have been met. I'm sorry to
have troubled you." info;
In this section, the CellsPended question is designed to store the names of the brands that were pended because their cells were the least full so that this information is readily available when interviews are restarted.
The routing section of the script is:
IceCream.Ask()
If Not _
(PendQuotas(IceCream, PendedBrands, QuotaEngine.QuotaGroups["IceCream"])) Then
'Quotas full so terminate interview
IOM.Texts.InterviewStopped= AllFull.Label
IOM.Terminate(Signals.sigOverQuota)
End If
FlavorGrid.QuestionFilter = PendedBrands.Response
FlavorGrid.Ask()
' Pend quotas and return names of pended brands
Function PendQuotas(QuotaQuestion, CellsPended, QuotaGroupToPend)
Dim pend_result, orig_answers
PendQuotas = False
' A new interview so pend brands and set question filter
If (CellsPended.Info.OffPathResponse Is Null) Then
pend_result = QuotaGroupToPend.Pend()
If (IsSet(pend_result,QuotaResultConstants.qrWasPended)) Then
' Save the pended cell information
CellsPended.Response.Value = _
CreateFilter(CellsPended.Categories, QuotaGroupToPend.Quotas)
PendQuotas = True
Exit Function
End If
' Snapback/restarted interview. Re-pend originally pended brands if any
' of those cells are still unfilled. If some are now full, pend only the
' unfilled ones. Set/reset question filter accordingly.
Else
If (QuotaQuestion.ContainsAny(CellsPended.Info.OffPathResponse)) Then
orig_answers = QuotaQuestion.Response.Value
QuotaQuestion.Response.Value = _
QuotaQuestion.Response.Value * CellsPended.Info.OffPathResponse
pend_result = QuotaGroupToPend.Pend()
QuotaQuestion.Response.Value = orig_answers
If (IsSet(pend_result,QuotaResultConstants.qrWasPended)) Then
CellsPended.Response.Value = _
CreateFilter(CellsPended.Categories, QuotaGroupToPend.Quotas)
PendQuotas = True
Exit Function
End If
' All originally pended cells are full so flag for termination.
PendQuotas = False
End If
End If
End Function
' Build list of names of pended brands
Function CreateFilter(Categories, Quotas)
Dim pended_quota, filter
For Each pended_quota In Quotas.WasPendedList
filter = filter + GetCategoryFromQuota(Categories,pended_quota)
Next
CreateFilter = filter
End Function
' Get category names of pended brands
Function GetCategoryFromQuota(Categories, Quota)
Dim category
GetCategoryFromQuota = "{}"
For Each category in Categories
If (Find(Quota.Expression, "{" + category.Name + "}") >= 0) Then
GetCategoryFromQuota = CCategorical(category)
Exit Function
End If
Next
End Function
The key part of this script is the PendQuotas function that checks and pends quotas. It separates interviews into new interviews and restarted or replayed interviews. A new interview is one in which the CellsPended question has no off-path response; that is, it has never been answered. Restarted interviews that have previously passed through quota control will have the names of the pended brands stored in this question.
If this is a new interview, the quota-controlled responses are checked to see which ones have the least full cells, and the two cells with the lowest counts are pended. PendQuotas calls the CreateFilter function to build a list of the names of the pended categories and this function calls GetCategoryFromQuota to convert those names into category values so that they can be assigned as the answers to the CellsPended question.
If this a restarted or replayed interview, PendQuotas starts by checking whether the current answers to the quota-controlled question include any of the cells that were previously pended for this interview. In an interview that is restarted from sample management this will always be the case, but for a replay after a snapback it is possible that the respondent may have chosen a completely different set of answers so there will be no correlation with the pended cells at all. The statement that compares the previously pended cells with the current answers is:
QuotaQuestion.Response.Value = QuotaQuestion.Response.Value * CellsPended.Info.OffPathResponse
The * symbol is the intersection operator (see
Categorical set logic). It merges the contents of two lists to produce a list of values that are present in both lists. In other words, it sets the value of the quota-controlled question to be the brands that were chosen this time and that were pended last time. Brands chosen this time but not pended last time and brands that were pended last time but not chosen this time are ignored.
Note Although this statement overwrites the brands that the respondent actually chose with the brands that we want to try pending, the assignment is only temporary. The respondent's answers are saved in the temporary orig_answers variable before the comparison is made, and these are set back into the question once the quota cells have been pended.
The script attempts to pend the two least full cells from this list. If the cells can be pended, the interview continues, otherwise it is terminated. The target for each brand is two and only two cells can be pended per interview.
The following table shows the results of five interviews. These interviews were the first that took place on a new project. They were run consecutively in the order shown and no other interviews took place during this period.
Interview ID
|
IceCream
|
PendedBrands
|
FlavorGrid
|
1
|
Alpine, Helen Bradley's, Dairy Fresh
|
Alpine, Dairy Fresh
|
Answered
|
2
|
Alpine, Helen Bradley's, Dairy Fresh
|
Helen Bradley's, Dairy Fresh
|
Click Stop
|
3
|
Helen Bradley's, Dairy Fresh
|
Helen Bradley's, Dairy Fresh
|
Answered
|
2 (Restarted)
|
Alpine, Helen Bradley's, Dairy Fresh
|
Helen Bradley's
|
Answered
|
4
|
Dairy Fresh, Kentish Farm, Alsace
|
Kentish Farm, Alsace
|
Click Previous to go back to IceCream
|
4 (Snapback)
|
Alpine, Finborough
|
Interview terminated
|
|
5
|
Helen Bradley's, Kentish Farm, Alsace
|
Kentish Farm, Alsace
|
Click Previous to go back to IceCream
|
5 (Snapback)
|
Alpine, Finborough, Alsace
|
Alsace
|
Answered
|
Interviews 1 to 3 show the effect of stopping an interview and then restarting it after some of the quotas that were originally pended for that interview have been filled. When interview 2 is stopped, the pend counts for Helen Bradley's and Dairy Fresh are rolled back so that there is still two interviews possible for Helen Bradley's and one interview possible for Dairy Fresh. At the end of interview 3 the quota Dairy Fresh has been filled, so when interview 2 restarts only the quota for Helen Bradley's can be pended. The quota for Alpine cannot be pended even though it is still unfilled because it was not one of the brands that was originally pended for the interview.
Interview 4 shows the result of snapping back and completely changing the brands used. Even though the quotas for Alpine and Finborough are not full, the interview is terminated because they are not the brands that were originally pended for this interview.
Compare that with interview 5 in which only one of the pended answers is changed. Alsace was one of the pended brands and it remains available for pending after the snapback, so the interview continues with just this brand pended.
In most cases, you will want to extend the script so that it allows other cells to be pended if the original least full cells are no longer available for whatever reason. For a way of doing this, see
When the original least-full cells are not available.
See also