Descriptive Representation Calculator

Tutorial: Using the DescriptiveRepresentationCalculator R Package

Listen to Post
Listen to post 6:36

Welcome to a tutorial page for the DescriptiveRepresentationCalculator R package. This package implements methods for analyzing descriptive representation—specifically, comparing how well a political body “looks like” the population it represents along different dimensions of identity, using a random sampling baseline as a point of comparison. It is based on “The Composition of Descriptive Representation” by John Gerring, Connor T. Jerzak, and Erzen Oncel (2023) in APSR (doi.org/10.1017/S0003055423000680).

Below, you’ll find guidance on installing the package, using its core functions, and interpreting your results. We will walk through each function with example code snippets so you can get started right away in R.

[Package Documentation] [.bib]
[Results from the Calculator for 156 countries]

Table of Contents

  1. Overview
  2. Installation
  3. Key Concepts
  4. Core Functions
  5. Example Workflow
  6. Interpreting Results
  7. Interactive Demo
  8. References

1. Overview

What Is Descriptive Representation?

Descriptive representation asks whether the demographic (or identity-based) attributes of leaders mirror those of the population. For instance:

  • Do the language groups in a country’s legislature roughly match the language groups in the general population?
  • Are women represented in parliament at about the same rate as their share of the population?
  • Are religious groups roughly proportionally represented in the cabinet?

Package Goals

  • Compute expected representation under random sampling: How much representation would we expect to see if members of a political body were chosen randomly from the public?
  • Compute observed representation: Given data on who actually holds office, how close is the match to the population shares?
  • Compute residual (unexplained) variation: How much of the gap between the observed and the expected representation is left unexplained by chance alone?

These questions are crucial for understanding where descriptive representation falls short and how much of that shortfall might be attributed to “coordination problems,” institutional factors, or other mechanisms highlighted by Gerring, Jerzak, and Oncel (2023).

2. Installation

The package DescriptiveRepresentationCalculator depends on base R functions and requires R 3.3.3 or higher. If you have a clone of the GitHub repository, you can install it directly using:

# install.packages("devtools") # if not already installed
library(devtools)

install_github("cjerzak/DescriptiveRepresentationCalculator-software")

Once installed, load the package:

library(DescriptiveRepresentationCalculator)

3. Key Concepts

  • Population Shares (PopShares): A numeric vector containing the proportions of each social group in the population. For example, if 40% of a country’s citizens are in Group A, 30% in Group B, and 30% in Group C, then PopShares = c(0.4, 0.3, 0.3).
  • Body Shares (BodyShares): The proportions of each social group in a specific political body (e.g., a legislature or cabinet). If, in the same example, the 50-person legislature has 20 members of Group A, 25 of Group B, and 5 of Group C, then BodyShares = c(0.4, 0.5, 0.1).
  • Body Size (BodyN): The total number of seats or members in the body (e.g., BodyN = 50).
  • Affine Transformation Parameters (a, b): Control how absolute deviation is re-weighted and re-scaled in the representation index. The default values (a = -0.5, b = 1) produce the Rose Index of Proportionality.

4. Core Functions

The package provides the following primary functions:

  1. ExpectedRepresentation()
  2. ObservedRepresentation()
  3. SDRepresentation()
  4. RelativeRepresentation()

Each is detailed below.

1. ExpectedRepresentation()

Purpose:
Computes the expected degree of representation for one or more groups in a political body, assuming that leaders are chosen randomly from the general population (a “random sampling” model).

Usage:

ExpectedRepresentation(PopShares, BodyN, a = -0.5, b = 1)

Arguments:

  • PopShares: Numeric vector of group-level population proportions (must sum to 1 if all relevant groups are accounted for).
  • BodyN: Positive integer for the size (number of seats) of the political body.
  • a, b: Parameters for affine transformation (default is a = -0.5, b = 1).

Returns:

  • A single numeric value corresponding to the expected representation index.

Example:

# install.packages("devtools") # if not already installed
library(devtools)

# Suppose we have 3 groups in the population with proportions 1/3, 2/3, and 1/3
PopShares_example <- c(1/3, 2/3, 1/3)

# Body size of 50 seats
BodyN_example <- 50

# Compute expected representation
ExpectedRep <- ExpectedRepresentation(PopShares = PopShares_example, BodyN = BodyN_example) print(ExpectedRep) # [1] 0.77

2. ObservedRepresentation()

Purpose:
Computes the observed degree of representation in a political body given either (1) the individual-level identity of each member (BodyMemberCharacteristics), or (2) the group-level shares of the body (BodyShares).

Usage:

ObservedRepresentation(BodyMemberCharacteristics = NULL,
PopShares,
BodyShares = NULL,
a = -0.5,
b = 1)

Arguments:

  • BodyMemberCharacteristics: Vector specifying a characteristic (e.g., “A,” “B,” “C”) for each member of the body. If this is provided, the function will internally compute BodyShares.
  • PopShares: Numeric vector of population shares for each group.
  • BodyShares: (Optional) Numeric vector of the body’s group shares. If provided, it overrides BodyMemberCharacteristics.
  • a, b: Parameters for affine transformation (default a = -0.5, b = 1).

Returns:

  • A single numeric value indicating how closely the body mirrors the population along the chosen dimension(s).

Example (specifying each member’s characteristic):

# Body has 6 members with traits: A, A, C, A, C, A
BodyMemberCharacteristics_example <- c("A", "A", "C", "A", "C", "A")

# Population shares for 3 groups: A (1/3), B (2/3), C (1/3)
PopShares_example <- c("A" = 1/3, "B" = 2/3, "C" = 1/3)

# Compute observed representation
ObsRep <- ObservedRepresentation(
BodyMemberCharacteristics = BodyMemberCharacteristics_example,
PopShares = PopShares_example
)

print(ObsRep)

Example (specifying body shares directly):

# Suppose we already know that in a 50-member body:
# 20% are Group A, 60% are Group B, 20% are Group C
BodyShares_example <- c("A"=0.2, "B"=0.6, "C"=0.2)

ObsRep_direct <- ObservedRepresentation(
PopShares = PopShares_example,
BodyShares = BodyShares_example
)
print(ObsRep_direct)

3. SDRepresentation()

Purpose:
Computes how much of the representation outcome remains unexplained by a simple random sampling model. In statistical terms, it estimates the residual standard deviation by simulating the possible random draws from the population.

Usage:

SDRepresentation(PopShares, BodyN, a = -0.5, b = 1, nMonte = 10000)

Arguments:

  • PopShares: Numeric vector of group-level population proportions.
  • BodyN: Positive integer for the body size.
  • a, b: Parameters for affine transformation (default a = -0.5, b = 1).
  • nMonte: Number of Monte Carlo iterations (default 10000).

Returns:

  • A single numeric value: the standard deviation of observed representation around the expected representation in a random sampling scenario.

Example:

# Suppose we already know that in a 50-member body:
# 20% are Group A, 60% are Group B, 20% are Group C
BodyShares_example <- c("A"=0.2, "B"=0.6, "C"=0.2)

ObsRep_direct <- ObservedRepresentation(
PopShares = PopShares_example,
BodyShares = BodyShares_example
)
print(ObsRep_direct)

4. RelativeRepresentation()

Beyond the three main functions, the package also provides RelativeRepresentation(), which calculates the difference between observed and expected representation. You can optionally standardize this difference by the standard deviation of representation under random sampling:

RelativeRepresentation(
  BodyMemberCharacteristics,
  PopShares,
  a = -0.5, b = 1,
  standardize = FALSE,
  nMonte = 10000
)

Use standardize = TRUE to divide by the value returned by SDRepresentation().

5. Example Workflow

Below is a hypothetical end-to-end scenario:

Specify Groups & Population Shares
Let’s say you have data on religion in a hypothetical country with three major groups:
PopShares_religion <- c("GroupA" = 0.3, "GroupB" = 0.5, "GroupC" = 0.2)

Then, define the number of people in the legislature:
BodyN_legislature <- 100

Compute Expected Representation

exp_rep <- ExpectedRepresentation( PopShares = PopShares_religion, BodyN = BodyN_legislature )


Gather Observed Data
Suppose you’ve coded each legislator’s religious identity:

legislature_identities <- c(rep("GroupA", 25), rep("GroupB", 60), rep("GroupC", 15)) # total 100

Compute Observed Representation

obs_rep <- ObservedRepresentation( BodyMemberCharacteristics = legislature_identities, PopShares = PopShares_religion )


Assess Residual Variability
How far typical random draws might vary from the expected value?

sd_rep <- SDRepresentation( PopShares = PopShares_religion, BodyN = BodyN_legislature )


Compare Results
exp_rep might be something like 0.84, indicating that if seats were allotted by chance, we’d expect a 0.84 representation score.obs_rep might be 0.88, showing that this legislature is slightly more representative than a purely random draw. sd_rep might be 0.05, indicating a moderate spread. A difference of 0.04 (0.88 – 0.84) could be notable if it’s larger than typical random fluctuations.

6. Interpreting Results

  1. Indices near 1
    An observed representation index close to 1 means the political body’s shares for each group almost exactly match population shares.
    –
  2. Indices near 0
    If you observe observed representation index values closer to 0, it indicates a severe misalignment: certain groups are starkly over- or under-represented relative to their population share.
    –
  3. Using ExpectedRepresentation() as a Baseline
    By comparing ObservedRepresentation() to ExpectedRepresentation(), you can see whether a political body is doing better or worse than under random chance.
    –
  4. Variability from SDRepresentation()
    If SDRepresentation() is large, then chance processes can produce many configurations of body composition. If it’s small, then almost any real-world instance will cluster near the expected representation baseline.

7. Interactive Demo

8. References

[Return to Home]