Tutorials › Exam PA - Predictive Analytics › Category Proportions and Marginal Totals

Exam PA · Data Structures and Exploratory Summaries · Tutorial 115 of 966

Category Proportions and Marginal Totals

Use prop.table() and marginal totals to describe category shares accurately, with the denominator matched to the question.

Beginner 11 min read

What You'll Learn

  • Convert one-way category counts to proportions with prop.table().
  • Distinguish overall cell proportions from row-wise and column-wise proportions.
  • Use margin.table() and addmargins() to obtain marginal totals.
  • Identify the denominator and interpretation for each proportion.
  • Check proportion tables using their expected sums and total counts.
  • Recognize and correct common denominator errors in R.

From Frequency Counts to Category Shares

A frequency table answers “how many?” A proportion table answers “what share?” That change is useful when describing a categorical variable, comparing category distributions, or summarizing the cells of a two-way table. The key decision is the denominator: a proportion may refer to the whole data set, one row, or one column.

In R, prop.table() converts counts to proportions. For a one-way table, it divides each count by the grand total. For a two-way table, its margin argument can instead normalize within rows or columns. The numbers can look similar, but their meanings differ, so state the denominator and interpretation when reporting them.

Definition: If a frequency table contains counts \(n_1,\ldots,n_k\) and total \(N=\sum_{j=1}^{k}n_j\), the proportion for category \(j\) is \(n_j/N\). In a two-way table, let \(n_{ij}\) be the count in row \(i\), column \(j\), and let \(N\) be the grand total. The overall cell proportion is \(n_{ij}/N\). The row proportion is \(n_{ij}/n_{i+}\), where \(n_{i+}\) is that row's total; the column proportion is \(n_{ij}/n_{+j}\), where \(n_{+j}\) is that column's total.

One-Way Proportions

For a one-way frequency table, the default call, prop.table(tab), divides every category count by the total count. For example, a hypothetical table of enrollment choices might report 48 Standard, 32 Enhanced, and 20 Basic selections. The total is \(48+32+20=100\), so the corresponding proportions are \(48/100=0.48\), \(32/100=0.32\), and \(20/100=0.20\). Together they sum to 1.

In R, first make the frequency table, then pass it to prop.table(). The output is a set of proportions, not percentages. Multiply by 100 only when you specifically want percentage values for presentation. Do not round each count or proportion before calculating the rest of the table; retain full precision in R and round only for display.

Worked Example: Proportions of Hypothetical Service Selections

A hypothetical service team records 60 selections: 27 for Remote, 21 for In-person, and 12 for Hybrid service. Find each category's share, identify the largest share, and verify the result. The method is a one-way frequency table followed by prop.table(); it avoids treating a count as though it were already a proportion.

Step 1: Calculate the total. \(N=27+21+12=60\).

Step 2: Divide each count by 60. Remote is \(27/60=0.4500\); In-person is \(21/60=0.3500\); Hybrid is \(12/60=0.2000\). To obtain these values in R, use a frequency table such as tab = table(service) followed by prop.table(tab).

Step 3: Interpret and check. Remote accounts for the largest share, 0.4500, or 45.00%. The proportions sum to \(0.4500+0.3500+0.2000=1.0000\), which agrees with the full set of 60 selections. The proportions are reported to four decimal places; the exact fractions also sum to 1.

Common mistake avoided: Reporting 27 as the Remote proportion confuses a count with a share. The proportion is 27 divided by the 60 observations, not 27 by itself.

Two-Way Tables: Overall, Row, and Column Proportions

A two-way frequency table counts observations classified by two categorical variables. Its cells give joint counts, while the sums across rows and columns are marginal totals. In R, prop.table(tab) divides every cell by the grand total. For row-wise proportions, use prop.table(tab, margin = 1); for column-wise proportions, use prop.table(tab, margin = 2).

For a table with \(r\) rows and \(c\) columns, row \(i\)'s total is \(n_{i+}=\sum_{j=1}^{c}n_{ij}\), and column \(j\)'s total is \(n_{+j}=\sum_{i=1}^{r}n_{ij}\). Thus, row proportions answer “within this row, what share is in each column?” Column proportions answer “within this column, what share is in each row?” The overall proportion answers “what share of all observations falls in this cell?”

$$ \text{Overall: } \frac{n_{ij}}{N} \qquad \text{Row-wise: } \frac{n_{ij}}{n_{i+}} \qquad \text{Column-wise: } \frac{n_{ij}}{n_{+j}} $$

These formulas explain the normalization performed by prop.table(). For overall proportions, summing over all cells gives \(\sum_i\sum_j n_{ij}/N=N/N=1\). Within a row, summing the row proportions gives \(\sum_j n_{ij}/n_{i+}=n_{i+}/n_{i+}=1\). Within a column, the corresponding sum is \(\sum_i n_{ij}/n_{+j}=n_{+j}/n_{+j}=1\). Therefore, overall proportions sum to 1 across the entire table; row proportions sum to 1 across each row; and column proportions sum to 1 down each column.

Worked Example: Choosing the Denominator for a Two-Way Table

In a hypothetical sample of 100 applications, 24 arrived through the Web route and were Accepted, 16 arrived through the Web route and were Referred, 30 arrived through the Agent route and were Accepted, and 30 arrived through the Agent route and were Referred. Find the overall share for each cell, the acceptance proportion within each route, and the route composition among Accepted applications. The method is to calculate the relevant marginal totals first and then select the denominator that matches each question.

Step 1: Set up the table and totals. In R, the counts can be represented as tab = matrix(c(24, 16, 30, 30), nrow = 2, byrow = TRUE, dimnames = list(Route = c("Web", "Agent"), Outcome = c("Accepted", "Referred"))). The Web row total is \(24+16=40\), the Agent row total is \(30+30=60\), the Accepted column total is \(24+30=54\), and the Referred column total is \(16+30=46\). The grand total is \(40+60=100\).

Step 2: Calculate overall cell proportions. Divide each cell by 100: Web-Accepted is \(24/100=0.2400\); Web-Referred is \(16/100=0.1600\); Agent-Accepted is \(30/100=0.3000\); and Agent-Referred is \(30/100=0.3000\). In R, prop.table(tab) returns these overall proportions.

Step 3: Calculate acceptance within route. Use each row total as the denominator. For Web, the acceptance proportion is \(24/40=0.6000\), and the referral proportion is \(16/40=0.4000\). For Agent, the acceptance proportion is \(30/60=0.5000\), and the referral proportion is \(30/60=0.5000\). In R, prop.table(tab, margin = 1) gives these row-wise proportions. Each row sums to 1.

Step 4: Find route composition among Accepted applications. The denominator is the Accepted column total, 54. The Web share is \(24/54=0.4444\) to four decimal places, and the Agent share is \(30/54=0.5556\). Use prop.table(tab, margin = 2) for column-wise proportions; its Accepted column contains these values. They sum to 1 after rounding.

Check and common mistake avoided. The four overall proportions sum to \(0.2400+0.1600+0.3000+0.3000=1.0000\). The Web acceptance proportion is \(24/40=0.6000\), not \(24/100=0.2400\): the first answers the within-Web question, while the second is the Web-Accepted share of the whole sample.

Marginal Totals in R

Marginal totals summarize a two-way frequency table along one dimension. The base R function margin.table(tab, 1) returns row totals, and margin.table(tab, 2) returns column totals. Alternatively, addmargins(tab) displays both sets of totals and the grand total alongside the original counts. These are counts, not proportions.

You can obtain marginal proportions from the totals by dividing by the grand total. For the application table above, the route shares are \(40/100=0.4000\) for Web and \(60/100=0.6000\) for Agent. The outcome shares are \(54/100=0.5400\) for Accepted and \(46/100=0.4600\) for Referred. These also appear as the row and column sums of the overall-proportion table, respectively.

Worked Example: Adding and Interpreting Marginal Totals

A hypothetical portfolio review classifies 80 records by segment and selected coverage. Segment A has 18 Basic and 12 Plus records; Segment B has 10 Basic and 40 Plus records. Find the marginal counts, the overall coverage shares, and the share of Segment A among Basic records. The method uses row and column sums, then divides by the grand total or the named column total. It avoids using a row total when the question asks about the composition of a column.

Step 1: Calculate all marginal counts. Segment A has \(18+12=30\) records, and Segment B has \(10+40=50\). Basic has \(18+10=28\), and Plus has \(12+40=52\). The grand total is \(30+50=80\), which also equals \(28+52=80\). In R, addmargins(tab) adds these row totals, column totals, and the grand total to the count table. The row and column counts can also be computed separately with margin.table(tab, 1) and margin.table(tab, 2).

Step 2: Calculate overall coverage shares. Basic is \(28/80=0.3500\); Plus is \(52/80=0.6500\). These are marginal proportions because each divides a marginal count by the grand total. The shares sum to \(0.3500+0.6500=1.0000\).

Step 3: Calculate Segment A's share among Basic records. The wording specifies “among Basic records,” so the denominator is the Basic column total, 28. The answer is \(18/28=0.642857\ldots\), or 0.6429 to four decimal places (64.29%). This is a column-wise proportion, obtained for that cell by prop.table(tab, margin = 2).

Step 4: Check the interpretation. Segment B's share among Basic records is \(10/28=0.357142\ldots\), or 0.3571 to four decimal places. The two Basic-column shares sum to 1 before rounding; their displayed values sum to 1.0000. By contrast, Segment A's share among all records is \(30/80=0.3750\), a different quantity.

Common mistake avoided: Dividing 18 by Segment A's total of 30 gives \(18/30=0.6000\), the Basic share within Segment A. It does not answer the question about Segment A among Basic records. Read “within,” “among,” or “of all” as a clue to the denominator.

A Reliable Workflow and Common Traps

Before calculating a proportion, translate the question into a denominator. “Of all records” means divide by the grand total. “Within this row” means divide by that row total. “Among this column” means divide by that column total. Then choose the corresponding R operation and verify that the proportions sum to 1 in the direction that was normalized.

1
Inspect the count table.
Identify its categories, cell counts, and any zero-count categories shown. Establish whether the table represents the observations relevant to the question.
2
Name the denominator.
Choose the grand total, the specified row total, or the specified column total based on the wording of the requested share.
3
Calculate and interpret.
Use prop.table() with the appropriate margin, then state what the resulting proportion describes in context.
4
Check the result.
Confirm the expected sum: 1 over the full table for overall proportions, across each row for margin = 1, or down each column for margin = 2.

A common exam trap is to report a correctly calculated proportion with the wrong interpretation. For example, \(24/100=0.2400\) and \(24/40=0.6000\) can both be correct calculations from the application table. The first is the share of all applications that are Web-Accepted; the second is the acceptance share among Web applications. The data and numerator are the same, but the denominator changes the question being answered.

Another trap is to treat marginal totals as though they were proportions. The value 54 in the Accepted margin is a count. The Accepted share of all applications is \(54/100=0.5400\), whereas the Web share among Accepted applications is \(24/54=0.4444\). Label which of these is being reported. This careful distinction makes a frequency-table summary reproducible and prevents a descriptive result from being overstated.

Key takeaway: prop.table(tab) gives whole-table shares; prop.table(tab, margin = 1) gives within-row shares; and prop.table(tab, margin = 2) gives within-column shares. Use margin.table() or addmargins() for count totals, and always name the denominator that gives the result its meaning. This data-summary skill is aligned with the SOA Exam PA (Predictive Analytics) syllabus.

Check Your Understanding

For each problem, identify the denominator before calculating. Proportions in the answers are rounded to four decimal places where needed.

  1. A hypothetical survey records 14 “North,” 21 “Central,” and 15 “South” responses. What is each region's overall proportion? (Answer: North 0.2800, Central 0.4200, South 0.3000.)
  2. A two-way table has row A counts 12 and 8, and row B counts 18 and 22. What are the row-wise proportions? (Answer: Row A 0.6000 and 0.4000; Row B 0.4500 and 0.5500.)
  3. Using the table in Question 2, find both column totals and the proportion of all observations in row B, second column. (Answer: Column totals 30 and 30; the overall cell proportion is \(22/60=0.3667\).)
  4. A hypothetical table has Group X counts 9 and 21, and Group Y counts 15 and 15, with columns labeled Selected and Not selected in that order. What share of Selected records is from Group Y, and what is the Group Y row total? (Answer: \(15/(9+15)=0.6250\) of Selected records are from Group Y; Group Y's row total is 30.)
  5. A table has counts 16 and 24 in its first row and 14 and 26 in its second row. Find the marginal proportion for the second column and the first-column share within the first row. (Answer: Second-column marginal proportion \(50/80=0.6250\); first-column share within the first row \(16/40=0.4000\).)
Clinical Biostats