Temper market share data

Updated at April 24th, 2024

Respondents can overstate behavior changes in an anticipated future share distribution when one or more new products offered. In this tutorial we demonstrate how a scale question can be used to adjust overstated market share distributions in an exercise called "tempering".

In this example, we use a data process to calculate a tempered share by reducing the new product shares, and redistributing the reduced shares back into the products that respondents currently use.

Example questionnaire

A survey asks for current prescribing behavior in Q100. Then in Q200 the survey asks for a new distribution assuming that Product X and Y are available for prescribing. If Product X and Y receive larger market shares than expected, you can use a scale question such as Q210 to temper down the stated shares.

Q100. Approximate what percentage of the following products do you currently prescribe:

Q100_1 Product A ____ %
Q100_2 Product B ____ %
Q100_3 Product C ____ %

Q200. Should Product X and Product Y be available, what will your future prescribing distribution be:

Q200_1 Product A ____ %
Q200_2 Product B ____ %
Q200_3 Product C ____ %
Q200_4 Product X ____ %
Q200_5 Product Y ____ %

Q210. What is your overall likelihood of using Product X and Y

Q210_1 Product X:

1: Not at all likely
2: Somewhat likely
3: Fairly likely
4: Very likely

Q210_2 Product Y:

1: Not at all likely
2: Somewhat likely
3: Fairly likely
4: Very likely

Choose a factor to weight stated shares by 

Determine a likelihood factor (%) for each value in Q210. For example, if Q210_1 (Product X) had an average value of "2: Somewhat likely", then we will temper using a likelihood factor of 25%.  We are essentially weighting stated future shares for Product X and Y by their likelihood to prescribe in Q210.

Assumptions:

1. This is the scale for tempering the shares in Q200_4 and Q200_5 based on Q210_1, and Q210_2:

1 (Not at all likely): 0%
2 (Somewhat likely): 25%
3 (Fairly likely): 50%
4 (Very likely): 75%

2. Tempered shares for Products X and Y are calculated by subtracting tempered future shares (column N) from the stated future shares (column E). The stated current shares (Q100) are used to distribute the tempered shares. 

(Note - array used to distribute shares need to be greater than or equal to zero individually, and sum to a positive number if any shares are to be distributed)

Calculated Example:

An example of calculation for one respondent would be:

 

Below is a sample code for the data process:

Data process code:

/**
 * @method data process
 * 
 * Tempering calculations
 * 
 * Tempering - please find the scale attached below
 
 * Q100 - Current distribution (baseline) - use for distribution
 * Q200 - Product X and Y, future distribution 
 * Q210 - Likelihood of Product 1
*/

// Bring in data 
var rows = data['main']

/**
 * @method temper
 * @param PREFIX - to add in front of the redistribution_array and temper_array
 * @param tempering - specifies tempering factor for each possible response in scale_array
 * @param distribution_array - array of column names corresponding to percent of patients on each (current) therapy; used as reference for proportionally redistributing tempered shares..
 * @param redistribution_array - array of column names corresponding to percent of patients on each (current) therapy in a future scenario; these shares will be increased as a result of tempering
 * @param temper_array - array of column names of potential new future therapy; these are the values to be reduce via tempering;
 * @param scale_array - array of column names of physicians' estimate of likelihood to prescribe new product at all
 *
 * Algorithm
 * 1. calculate the tempering factor for each item in the temper_array using the scale_array and the tempering factor object.
 *    The tempering factor object should have attributes for each valid response in the scale array.  (e.g. scale array answer ranges from 0 to 10, and the tempering object has the tempering values for each of 0 to 10.)
 * 2. Take the items in the temper_array, and reduce them by the tempering factor calculated by 1.
 * 3. Calculate the redistribution_total by summing up the reductions in the temper_array due to tempering.
 * 4. Distribute the 3. into the redistribution_array based on distribution_array.  
 * 
 * 
 * Constraint 1: distribution_array and redistribution_array should be the same length, 
 * Constraint 2: temper_array and scale_array should be the same length
 * Constraint 3: distribution_array should have a non-zero sum
 *  
 * @example
 *    var prefix = "t_"  
 *    var tempering = tempering['initial'] // this is an object to interpret the scale array
 *    var tempering = {
 *    initial: {
 *        "1": 0.00,
 *        "2": 0.25,
 *        "3": 0.50,
 *        "4": 0.75
 *         }
 *     };
 *
 *    var d_array =  ["q100_1","q100_2","q100_3"];
 *    var r_array =  ["q200_1","q200_2","q202_3"];
 *    var t_array =  ["q200_4","q204_5"];
 *    var s_array =  ["q210_1","q210_2"];
 * 
 */
function temper(row, PREFIX,  tempering, distribution_array, redistribution_array, temper_array, scale_array) {


    var distribution_length = distribution_array.length
    var temper_length = temper_array.length
    var redistribution_total = 0;
    var distribution_total = 0


    // calculate total for the distribution total.  Need to make sure that The amount is non-zero, or else tempering amount should be left as NAs.
    
    for (d=0;d<distribution_length;d++){
        distribution_total = distribution_total + (+row[distribution_array[d]] || 0)
    }


    if (distribution_total >0) {
        
        for (t=0; t<temper_length; t++ ){
            var tempering_factor = tempering[row[scale_array[t]]]
            if (typeof tempering_factor == 'undefined') console.log("blank tempering factor", t, scale_array[t],temper_array[t], row[scale_array[t]], row[temper_array[t]],row.respid);
            row[PREFIX + temper_array[t]] = (+row[temper_array[t]] * tempering_factor) || 0;
            if (typeof row[PREFIX + temper_array[t]] == 'undefined') console.log("tempered undefined", PREFIX + temper_array[t], row[temper_array[t]],tempering_factor)
            redistribution_total += +row[temper_array[t]] - (+row[PREFIX + temper_array[t]]); 
        }
        
        for (d=0;d<distribution_length;d++){
            row[PREFIX + redistribution_array[d]] = +row[redistribution_array[d]] +  (row[distribution_array[d]]||0)/distribution_total * redistribution_total;
            if (typeof row[PREFIX + redistribution_array[d]] == 'undefined') console.log("redistribution undefined", PREFIX + redistribution_array[d], row[redistribution_array[d]],(row[distribution_array[d]]||0)/distribution_total,redistribution_total)
        }
    }      
}
var tempering = {
  initial: {
    "1": 0.00,
    "2": 0.25,
    "3": 0.50,
    "4": 0.75
  }
};


rows.forEach(function(row){
    // Setup tempering arrays.  Could create multiple sets:    
    var Q200_d_array =  ["q100_1","q100_2","q100_3"];
    var Q200_r_array =  ["q200_1","q200_2","q200_3"];
    var Q200_t_array =  ["q200_4","q200_5"];
    var Q200_s_array =  ["q210_1","q210_2"];
    // Run temper calculation to create t_Q200
     temper(row, 't_',  tempering['initial'], Q200_d_array, Q200_r_array,   Q200_t_array,   Q200_s_array)
})


return rows;
 

Was this article helpful?