Why Grouped Summaries Matter
An overall average can conceal differences in the records that make it up. For example, a single average claim cost does not show whether the average is similar across territories. A grouped summary organizes a numeric outcome by category, giving one summary for each category represented in the data.
In base R, aggregate() performs this task. This tutorial focuses on a common case: summarizing one numeric variable by one categorical variable, such as mean claim cost by territory. The output is useful for exploration, but it is descriptive: a difference between group averages does not by itself establish that group membership caused a difference in cost.
The Formula Interface to aggregate()
A clear way to use aggregate() is its formula interface. The variable to summarize goes to the left of ~; the categorical grouping variable goes to the right. The data argument names the data frame, and FUN names the function to apply.
For instance, if a data frame called claims contains numeric cost and categorical region, the following call calculates the mean cost by region:
aggregate(cost ~ region, data = claims, FUN = mean)
The returned data frame has a column for the grouping variable and a column for the summary. In this example, the columns are named region and cost. The values in the cost column are group means, not the original claim costs. Because the formula contains one response and one grouping variable, this call produces one summary measure for each observed region.
The function passed to FUN determines what the result means. With FUN = mean, it is a mean; with FUN = median, it is a median. The data and the chosen function should match the question. A mean cost is meaningful only if the response is numeric and its units are understood.
Choose the numeric variable to summarize, such as cost per claim.
Choose the categorical variable whose values define the groups, such as region.
For example, use
FUN = mean when the requested summary is the mean.Each row reports the selected summary for a group. Check which observations were included before interpreting it.
Worked Example: Mean Claim Cost by Region
A hypothetical insurer has recorded five claim costs, in dollars, for an exploratory exercise. Calculate the mean cost in each region and interpret the result.
| Region | Cost |
|---|---|
| North | 120 |
| North | 180 |
| South | 90 |
| South | 150 |
| West | 200 |
Method. Use the formula interface with cost as the numeric response, region as the grouping variable, and mean as the summary function.
R code: aggregate(cost ~ region, data = claims, FUN = mean)
North calculation. The two costs are 120 and 180, so the mean is \((120 + 180)/2 = 300/2 = 150\) dollars.
South calculation. The two costs are 90 and 150, so the mean is \((90 + 150)/2 = 240/2 = 120\) dollars.
West calculation. The only recorded cost is 200, so the mean is \(200/1 = 200\) dollars.
| region | cost |
|---|---|
| North | 150 |
| South | 120 |
| West | 200 |
The output says that the mean of the recorded costs is 150 dollars for North, 120 dollars for South, and 200 dollars for West. The West value is based on just one recorded claim, so it is that observation's cost rather than an average across several claims. The calculations from the input table agree with the returned summaries.
What a Group Mean Represents
For a group \(j\), let \(n_j\) be the number of included observations and let \(x_{ij}\) be observation \(i\)'s numeric value in that group. The group mean is the sum of the group's values divided by the number of included values:
This definition explains why the grouping variable matters: each observation is assigned to a category, and the function is applied only to the numeric values assigned to that category. The reported mean is therefore conditional on both the data included and the group definition. If a category is miscoded or a record is excluded, the output can change.
Worked Example: Reading a Summary with a Missing Cost
A hypothetical claims extract has a cost recorded for some claims but not all. Calculate the mean recorded cost by zone using the formula interface's default handling of missing values.
| Zone | Cost |
|---|---|
| Coastal | 40 |
| Coastal | Missing |
| Coastal | 80 |
| Interior | 60 |
| Interior | 120 |
Method. The default formula-interface behavior uses the default missing-value action, na.omit. Thus rows with a missing value in a variable in the formula are omitted from the calculation. Here the Coastal record with missing cost is not included.
R code: aggregate(cost ~ zone, data = claims, FUN = mean)
Coastal calculation. The included costs are 40 and 80. Their mean is \((40 + 80)/2 = 120/2 = 60\).
Interior calculation. Both costs are present. Their mean is \((60 + 120)/2 = 180/2 = 90\).
| zone | cost |
|---|---|
| Coastal | 60 |
| Interior | 90 |
These are means of the recorded, non-missing costs. They are not estimates of the missing cost, and the output does not show how many records were omitted. Before using a result, check whether missingness in either the response or the grouping variable may have removed records. A missing group label cannot be assigned to a named zone in this summary.
A useful check is to compare the number of values used in each manual calculation with the available non-missing data. Coastal has two included costs, not three; Interior has two. The displayed means follow from those included values.
Why Group Means Must Be Weighted to Recover an Overall Mean
A grouped table contains one mean per group, but those means do not generally have equal importance in an overall mean. A group with many observations contributes more individual values to the combined data than a group with few observations.
The relationship follows directly from the definition of a mean. Suppose there are \(J\) groups, each with \(n_j\) observations and mean \(\bar{x}_j\). The sum of the observations in group \(j\) is \(n_j\bar{x}_j\). Adding the group sums gives the total sum of all observations, and dividing by the total number of observations gives:
This is a weighted average of the group means, with each group's size as its weight. The identity applies when the group summaries use the same numeric observations that make up the overall mean. It does not say that an unweighted average of group means is generally the overall mean. Equal weighting happens to work when the group sizes are equal, or when the group means have special values that make the two calculations coincide.
Worked Example: Unequal Group Sizes and the Overall Mean
A hypothetical portfolio extract has two segments. Segment A has costs of 30 and 90 dollars. Segment B has costs of 20, 40, 60, and 80 dollars. Calculate each segment mean and the overall mean, then identify the error in averaging the segment means equally.
R code: aggregate(cost ~ segment, data = claims, FUN = mean)
Segment A. Its total cost is \(30 + 90 = 120\) dollars across \(n_A = 2\) claims. Its mean is \(120/2 = 60\) dollars.
Segment B. Its total cost is \(20 + 40 + 60 + 80 = 200\) dollars across \(n_B = 4\) claims. Its mean is \(200/4 = 50\) dollars.
Overall mean from the raw values. The total cost is \(120 + 200 = 320\) dollars, and the total number of claims is \(2 + 4 = 6\). Therefore the overall mean is \(320/6 = 53.333\ldots\) dollars, or 53.33 dollars when rounded to two decimal places.
Weighted check. Using the group means gives \(\{2(60) + 4(50)\}/6 = (120 + 200)/6 = 320/6 = 53.333\ldots\) dollars, the same overall result.
Common mistake. The unweighted average of the two group means is \((60 + 50)/2 = 55\) dollars. This is not the overall mean: it gives each segment equal weight even though Segment B has twice as many claims. The correction is to weight each mean by its group size, giving 53.33 dollars after rounding to two decimal places. The raw-data and weighted calculations agree, which checks the result.
Common Mistakes and Practical Checks
The call to aggregate() is short, but a correct interpretation depends on more than the syntax. In particular, distinguish the numeric response from the grouping variable, read the function that was applied, and establish which observations were included.
- Reversing the formula. In
cost ~ region, cost is summarized and region defines the groups. Reversing the roles does not express the intended numeric summary by category. - Calling the result an overall mean. Each output row is a group-specific summary. It is not a single summary for the full data frame.
- Giving each group mean equal weight. An unweighted average of group means is generally not the overall mean when group sizes differ.
- Ignoring missing values. Under the default formula-interface missing-value action, incomplete rows for formula variables are omitted. The summary describes the included records, not automatically every row originally present.
- Over-interpreting a difference. A grouped mean describes the data summarized. It does not establish why the group means differ or whether the difference will persist in another population.
As a final check, recompute at least one group from the underlying values, verify that the function matches the question, and make sure the units in the interpretation match the numeric variable. These checks help catch syntax errors as well as errors in reading the output.
aggregate(response ~ group, data = ..., FUN = ...) to summarize one numeric response separately by one categorical variable. Interpret each row as a group summary of the included observations, and use group sizes—not equal weights—when combining group means.
Check Your Understanding
For each problem, identify the grouped summary and check the arithmetic before interpreting the result.
- A hypothetical repair dataset has labor costs of 40 and 80 dollars for Shop A, and 100 dollars for Shop B. What does
aggregate(cost ~ shop, data = repairs, FUN = mean)return? (Answer: Shop A, 60 dollars; Shop B, 100 dollars.) - A hypothetical data frame has three North values, 10, missing, and 30, and two South values, 20 and 40. Using the formula interface with its default missing-value action, what mean is returned for each region? (Answer: North, 20; South, 30; the missing North value is omitted.)
- Segment C has values 15, 30, and 45; Segment D has values 50 and 70. What are the two segment means, the overall mean, and the unweighted average of the segment means? (Answer: C, 30; D, 60; overall mean, 42; unweighted average of group means, 45.)
- A hypothetical delivery dataset has times of 12, 20, and 28 minutes for the Phone channel, and 8 and 10 minutes for the Web channel. What does
aggregate(time ~ channel, data = deliveries, FUN = median)return? (Answer: Phone, 20 minutes; Web, 9 minutes.) - A grouped output reports a mean cost of 75 dollars for a category. Can this value alone establish that belonging to the category caused higher costs than in another category? (Answer: No. It is a descriptive group mean; by itself it does not establish a causal effect.)