Each of the standard panel analyses described below is illustrated in the QPack that can be downloaded from here. This can be uploaded to Displayr via these instructions: How to Create a Displayr Document Using a QPack.

Market share is computed by creating a summary table from the transactional database which indicates brand purchased and applying a weight which combines both quantity purchased and corrections for any skews in the individual-level database (see How to Weight with Panel Data).

Market share by segment is computed by first computing market share (see the previous section) and then selecting the segmentation variable in the table columns. For example, the chart below shows the Total % by segment and brand as a Mosaic Plot.

Market share over time is computed by first computing market share and then selecting a Date variable in the table columns. Note that the various tools for tracking data, such as time series charts and moving averages, are all applicable (see Tracking Study Best Practices). For example:

The previous market share computations are all shares of units purchased. They can be turned into share of value by constructing and applying a new weight variable which includes the price information via JavaScript code:

`quantity * Q.GetValue('Weight', 'Households.sav') * price`

## Penetration

Please refer to How to Weight with Panel Data for examples.

## Penetration for a specific period

The structure of panel data means that computation of time-based individual-level statistics is done using JavaScript and not by filtering. For example, the following formula computes category penetration over a three month period (from October to December):

```
var first_date = Q.EncodeDate(2010,10,1);
var last_date = Q.EncodeDate(2010,12,31);
var date = Q.GetValue('date', 'Transactions.sav');
var brand = Q.GetValue('brand', 'Transactions.sav');
var bought = 0;
for (var i = 0; i < date.length; i++) {
var cur_date = date[i];
if (cur_date >= first_date && cur_date <= last_date)
bought = 1;
}
bought
```

## Average number of transactions by segment

This is computed as a crosstab of the segment (in the table columns) and a variable containing the number of transactions, both of which are in the individual-level database, but where the number of transactions is created from the situational database using JavaScript:

```
var brand = Q.GetValue('brand', 'Transactions.sav');
brand.length
```

This can be written more concisely as:

`Q.GetValue('brand', 'Transactions.sav').length`

## Average number of purchases by segment

This is computed in the same manner as *Average number of transactions by segment*, except that the contents of the array are summed:

```
var quantity = Q.GetValue('quantity', 'Transactions.sav');
var sum = 0.0;
for (var i = 0; i < quantity.length; i++)
sum += quantity[i];
sum
```

## Brand switching

Brand switching tables are computed by creating two new variables in the individual-level study, one measuring the last brand purchased and the other measuring the previous purchase, where the variables are again computed from the situational data using JavaScript. The most recent purchase is computed using:

```
var brand = Q.GetValue('brand', 'Transactions.sav');
brand[brand.length - 1]
```

Note that:

- As described earlier,
`Q.GetValue('brand', 'Transactions.sav')`

returns an array. This array is in the same order as in the`Transaction.sav`data file and thus this formula assumes that`Transactions.sav`is ordered chronologically, with the oldest data at the top of the data file (please note that re-ordering the rows in the Data view does not have any impact on this calculation). -
`brand[brand.length - 1]`

returns the value of brand variable for each household’s last purchase (that is, the first entry in the array has the index of 0, the second has the index of 1 and thus`brand.length - 1`

refers to the final entry in the array).

The expression for the second last purchase is:

```
var brand = Q.GetValue('brand', 'Transactions.sav');
brand[brand.length - 2]
```

Note that significance tests applied to brand switching data are standard significance tests for crosstabs of categorical variables (i.e., they do not explicitly take into account that the data is switching data).

## Average quantity purchased by brand

The following expression computes the average quantity purchased of a particular brand by households:

```
var brand_index = 1; // this value determines which brand is used
var brand = Q.GetValue('brand', 'Transactions.sav');
var quantity = Q.GetValue('quantity', 'Transactions.sav');
var brand_purchases = 0.0;
for (var i = 0; i < brand.length; i++)
if (brand[i] == brand_index)
brand_purchases += quantity[i];
brand_purchases
```

Note that the first line specifies that the analysis is done using the brand with a **Value** of 1 in `transaction.sav`; to modify the expression for a different brand, you need to only change this line of code.

## Penetration by brand

Penetration by brand can be computed in a variety of ways. One way is to first compute Average quantity purchased by brand, then take a duplicate of this question and change its Structure to **Binary - Multi**, selecting all the non-zero values in **Count This Value**.

## Duplication

Duplication is computed by first computing *Penetration by brand*, and then selecting this variable set in both the table rows and columns.

Note that the significance tests applied to the duplication data are standard significance tests for crosstabs of categorical variables (i.e., they do not explicitly take into account that the data is duplication data).

This is computed as follows:

- For each brand, compute the average quantity purchased (see
*Average quantity purchased by brand*). - Create a
**Numeric - Multi**containing each of the variables. - Use the appropriate method for computing share (see How to Compute Share of Wallet, Spend, Mouth, etc. (i.e., Volumetric Analysis)).

This is computed in the same manner as with *Share of category requirements*, except that an additional set of variables is computed where the quantity purchased by brand is divided by the total number of purchases for each respondent. For example, for the first brand:

`brandA / nPurchases`

## 100% Loyalty

Computations of the proportion of buyers to be 100% loyal to a particular brand are computed in the same way as with Average share of category requirements, except that the Structure should be set to **Binary - Multi** and `brandA / nPurchases`

is replaced with:

```
if (brandA == 0) NaN;
else brandA == nPurchases
```

## Interpurchase interval

The following computation computes interpurchase interval (IPI) for households that have made two or more purchases:

```
var dates = Q.GetValue('date', 'Transactions.sav');
if (dates.length <= 1) NaN;
else Q.DayDif(dates[0], dates[dates.length - 1]) / (dates.length - 1)
```

This analysis assumes that the dates are ordered from oldest to newest (within each household’s data); if this was not the case, you would need to add code to compute the minimum and maximum date. Further, this order needs to be in the raw data file; re-ordering the data within Displayr will not have any impact upon this calculation (or any other calculation).

A histogram showing the average and median IPI is shown below.

## Date

A Numeric Variable with values that correspond to dates or times. Displayr constructs time variables using a series of assorted functions which can take Numeric Variables (e.g., with values like 20071203) and Text Variables (e.g., with values like 07-01-06) as inputs. This is done by constructing a Numeric Variable and entering an **Expression** of `Q.AsDate(v1)`

, where `v1` is the name of the variable). The dialog box for constructing Numeric Variables lists other functions as well. If the variable is categorical with values in the labels (e.g., a label of “1”), this can be addressed using `Q.Label`

(e.g., `Q.AsDate(Q.Label(v1))`

).