# Standard Panel Data Analyses

Each of the standard panel analyses described below is illustrated in `c:\Program Files\Q\Examples\Panel.Q`.

## Contents

- 1 Market share
- 2 Market share by segment
- 3 Market share over time
- 4 Share of value
- 5 Penetration
- 6 Penetration for a specific period
- 7 Average number of transactions by segment
- 8 Average number of purchases by segment
- 9 Brand switching
- 10 Average quantity purchased by brand
- 11 Penetration by brand
- 12 Duplication
- 13 Share of category requirements and share of throat or wallet
- 14 Average share of category requirements
- 15 100% Loyalty
- 16 Interpurchase interval
- 17 Date

Market share is computed by selecting a question in the blue drop-down menu 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 Weighting 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 Brown Drop-down Menu. For example, the chart below 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 question in the brown drop-down. Note that the various tools for tracking data, such as time series charts and moving averages, are all applicable (see Tracking Studies (Longitudinal Data Analysis). 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:

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

## Penetration

Please refer to Weighting 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 brown drop-down menu) 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 tab 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 Question Type to Pick Any, selecting all the non-zero values in **Count This Value**.

## Duplication

Duplication is computed by first computing *Penetration by brand*, and then selecting this question in both the blue and brown drop-down menus.

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 Number - Multi question 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`

Where there are more than a few brands you can save a lot of time by automatically reproducing formulas using **Insert Ready-Made Formula(s) > Use as Template for Replication**.

## 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 Question Type should be set to Pick Any 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 Q 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. Q 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))`).

Pages with syntax highlighting errors

Q Technical Reference

Q Technical Reference

Q Technical Reference > Setting Up Data > Creating New Variables

Q Technical Reference > Setting Up Data > Panel Data

Q Technical Reference > Updating and Automation > JavaScript

User Interface > JavaScript Variables > JavaScript Variables Examples Library