In this notebook, we will be estimating Zipf’s law using a variety of open, ready-to-use data sets and illustrate the striking empirical regularity. We will be focusing on metropolitan areas, which are larger than cities, and made of multiple counties. The file MSA-population-2015.xls is a spreadsheet with metropolitan areas ranked by population. You’ll recognize some of the most well-known American metropolitan areas, e.g. the New York tristate metropolitan area, the Los Angeles metro area.

Zipf’s law states that when regressing the log(rank) on the log(size) (where size is population) of a metro area, the coefficient is approximately -1.

\[ \log(rank) = \alpha - \zeta \cdot \log(size) + \varepsilon \]

Let’s estimate this relationship with U.S. data.

rm(list=ls())
library(readxl)
us.dta <- readxl::read_excel(path = 'MSA-population-2015.xlsx')
us.dta <- transform(us.dta,
                    log.rank            = log(1+Rank),
                    log.population.2015 = log(`2015 Estimate`))
plot(log.rank ~ log.population.2015, data = us.dta, main = "A test of Zipf's law for cities",
     xlab = '2015 Metro area population', ylab = 'log(Rank)')

There is a remarkable almost linear relationship between the log(Rank) and the log(population). Let’s add the OLS prediction on this graph, and let’s report the regression result.

zipfreg <- lm(log.rank ~ log.population.2015, data = us.dta)
summary(zipfreg)

Call:
lm(formula = log.rank ~ log.population.2015, data = us.dta)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.70848 -0.02489  0.01436  0.08204  0.18299 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         15.873248   0.074590   212.8   <2e-16 ***
log.population.2015 -0.860365   0.005865  -146.7   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1238 on 380 degrees of freedom
Multiple R-squared:  0.9826,    Adjusted R-squared:  0.9826 
F-statistic: 2.152e+04 on 1 and 380 DF,  p-value: < 2.2e-16
plot(log.rank ~ log.population.2015, data = us.dta, main = "A test of Zipf's law for cities",
     xlab = '2015 Metro area population', ylab = 'log(Rank)')
abline(zipfreg, lwd = 3, col='red')

Interestingly, while Gabaix (1999) and Krugman (1996) report a coefficient of 1, the coefficient we obtain here is about 0.9, close to 1 but not quite 1. What is striking however is how well the relationship predicts city size. A R Squared of 98% is hard to find in economics.

While the relationship performs well for the middle of the distribution (metro areas such as New Orleans and Salt Lake City), it performs less well for the largest metros (New York), but pretty badly at the bottom of the distribution (metro areas such as Rome, GA, or Fairbanks, AK). Gabaix (1999) provides an explanation based on the greater variance of industry-level shocks in those smaller metros.

Gabaix (1999) considered only 135 metros. How well does Zipf law perform with such a sample? Let’s try.

zipfreg.largest <- lm(log.rank ~ log.population.2015, data = us.dta[1:135,])
summary(zipfreg.largest)

Call:
lm(formula = log.rank ~ log.population.2015, data = us.dta[1:135, 
    ])

Residuals:
     Min       1Q   Median       3Q      Max 
-0.42975 -0.04315 -0.00596  0.03829  0.25084 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         17.99413    0.13929   129.2   <2e-16 ***
log.population.2015 -1.01134    0.01002  -100.9   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1004 on 133 degrees of freedom
Multiple R-squared:  0.9871,    Adjusted R-squared:  0.987 
F-statistic: 1.018e+04 on 1 and 133 DF,  p-value: < 2.2e-16

We get almost the same result as Gabaix (1999) ! Good to see that results can be replicated. The constant is significantly higher than in his paper though (10.53 in the paper vs. 17.99 here) but the slope is not statistically different from 1 (-1.01 with a standard error of 0.01).

plot(log.rank ~ log.population.2015, data = us.dta[1:135,], main = "A test of Zipf's law for U.S. Metro Areas",
     xlab = '2015 Metro area population', ylab = 'log(Rank)')
abline(zipfreg.largest, lwd = 3, col='red')

City Growth and Steady-State City Size Distribution

We’re going to look at the type of growth processes that can explain Zipf’s law. For that, we’re going to take the equations of Gabaix and simulate city sizes at different time horizons (a few years, a few decades) to see: (i) what growth processes (\(f(\gamma)\)) can explain the c.d.f. of city sizes and (ii) how many periods \(t\) are required to get a distribution that is not statistically different from Zipf.

N <- 200 # we start with 200 cities
T <- 1000 # and 100 years
get.next.distribution <- function(dist, mean, sd) {
  for (k in 1:length(dist)) {
    dist[k] <- max(dist[k] * rnorm(1, mean, sd), 1000)
  }
  
  dist
    
}
normalize.distribution <- function(dist) {
  
  dist <- dist / sum(dist)
  
}
make.zipf.dta <- function(dist) {
  
  dta <- data.frame(population = dist[order(dist, decreasing=TRUE)],
             rank       = 1:length(dist))
  
  dta$log.pop <- log(dta$population)
  dta$log.rank <- log(dta$rank)
  
  dta
  
}
distributions <- c()
distributions[[1]] <- rnorm(N,1,10)*10000 + 10000
for (k in 2:T) {
  distributions[[k]] <- get.next.distribution(distributions[[k-1]], 1, 0.1)
}
zipf.dta <- make.zipf.dta(distributions[[T]])
plot(log.rank ~ log.pop, data = zipf.dta, main = 'Monte Carlo Simulation -- Gibrat\'s law and Zipf\'s law',
     xlab = 'log(Population)', ylab = 'log(Rank)')
zipfreg <- lm(log.rank ~ log.pop, data = zipf.dta)
abline(zipfreg, lwd = 3, col = 'red')

summary(zipfreg)

Call:
lm(formula = log.rank ~ log.pop, data = zipf.dta)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.51958 -0.05271 -0.01006  0.06197  0.37649 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 11.056752   0.053610   206.2   <2e-16 ***
log.pop     -0.849949   0.006694  -127.0   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1054 on 198 degrees of freedom
Multiple R-squared:  0.9879,    Adjusted R-squared:  0.9878 
F-statistic: 1.612e+04 on 1 and 198 DF,  p-value: < 2.2e-16

Aggregation issues

europedta <- readxl::read_excel('European-metropolitan-areas.xlsx')
europedta <- transform(europedta,
                       log.rank = log(as.numeric(`Rank`)),
                       log.pop  = log(as.numeric(population))) 
plot(log.rank ~ log.pop, data = europedta)
europereg <- lm(log.rank ~ log.pop, data = europedta)
abline(europereg, lwd=3, col='red')

europereg <- lm(log.rank ~ log.pop, data = europedta)
summary(europereg)

Call:
lm(formula = log.rank ~ log.pop, data = europedta)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26718 -0.10875 -0.00365  0.09330  0.43020 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.57302    0.10141   45.10   <2e-16 ***
log.pop     -1.73948    0.07273  -23.92   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1634 on 22 degrees of freedom
Multiple R-squared:  0.963, Adjusted R-squared:  0.9613 
F-statistic:   572 on 1 and 22 DF,  p-value: < 2.2e-16
LS0tCnRpdGxlOiAiWmlwZidzIExhdyBmb3IgQ2l0aWVzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpJbiB0aGlzIG5vdGVib29rLCB3ZSB3aWxsIGJlIGVzdGltYXRpbmcgWmlwZidzIGxhdyB1c2luZyBhIHZhcmlldHkgb2Ygb3BlbiwgcmVhZHktdG8tdXNlIGRhdGEgc2V0cyBhbmQgaWxsdXN0cmF0ZSB0aGUgc3RyaWtpbmcgZW1waXJpY2FsIHJlZ3VsYXJpdHkuIFdlIHdpbGwgYmUgZm9jdXNpbmcgb24gX21ldHJvcG9saXRhbiBhcmVhc18sIHdoaWNoIGFyZSBsYXJnZXIgdGhhbiBjaXRpZXMsIGFuZCBtYWRlIG9mIG11bHRpcGxlIGNvdW50aWVzLiBUaGUgZmlsZSBfTVNBLXBvcHVsYXRpb24tMjAxNS54bHNfIGlzIGEgc3ByZWFkc2hlZXQgd2l0aCBtZXRyb3BvbGl0YW4gYXJlYXMgcmFua2VkIGJ5IHBvcHVsYXRpb24uIFlvdSdsbCByZWNvZ25pemUgc29tZSBvZiB0aGUgbW9zdCB3ZWxsLWtub3duIEFtZXJpY2FuIG1ldHJvcG9saXRhbiBhcmVhcywgZS5nLiB0aGUgTmV3IFlvcmsgdHJpc3RhdGUgbWV0cm9wb2xpdGFuIGFyZWEsIHRoZSBMb3MgQW5nZWxlcyBtZXRybyBhcmVhLgoKWmlwZidzIGxhdyBzdGF0ZXMgdGhhdCB3aGVuIHJlZ3Jlc3NpbmcgdGhlIGxvZyhyYW5rKSBvbiB0aGUgbG9nKHNpemUpICh3aGVyZSBzaXplIGlzIHBvcHVsYXRpb24pICBvZiBhIG1ldHJvIGFyZWEsIHRoZSBjb2VmZmljaWVudCBpcyBhcHByb3hpbWF0ZWx5IC0xLgoKJCQgXGxvZyhyYW5rKSA9IFxhbHBoYSAtIFx6ZXRhIFxjZG90IFxsb2coc2l6ZSkgKyBcdmFyZXBzaWxvbiAkJAoKTGV0J3MgZXN0aW1hdGUgdGhpcyByZWxhdGlvbnNoaXAgd2l0aCBVLlMuIGRhdGEuCgpgYGB7cn0Kcm0obGlzdD1scygpKQpsaWJyYXJ5KHJlYWR4bCkKdXMuZHRhIDwtIHJlYWR4bDo6cmVhZF9leGNlbChwYXRoID0gJ01TQS1wb3B1bGF0aW9uLTIwMTUueGxzeCcpCnVzLmR0YSA8LSB0cmFuc2Zvcm0odXMuZHRhLAogICAgICAgICAgICAgICAgICAgIGxvZy5yYW5rICAgICAgICAgICAgPSBsb2coMStSYW5rKSwKICAgICAgICAgICAgICAgICAgICBsb2cucG9wdWxhdGlvbi4yMDE1ID0gbG9nKGAyMDE1IEVzdGltYXRlYCkpCnBsb3QobG9nLnJhbmsgfiBsb2cucG9wdWxhdGlvbi4yMDE1LCBkYXRhID0gdXMuZHRhLCBtYWluID0gIkEgdGVzdCBvZiBaaXBmJ3MgbGF3IGZvciBjaXRpZXMiLAogICAgIHhsYWIgPSAnMjAxNSBNZXRybyBhcmVhIHBvcHVsYXRpb24nLCB5bGFiID0gJ2xvZyhSYW5rKScpCmBgYAoKVGhlcmUgaXMgYSByZW1hcmthYmxlIF9hbG1vc3QgbGluZWFyXyByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgbG9nKFJhbmspIGFuZCB0aGUgbG9nKHBvcHVsYXRpb24pLiBMZXQncyBhZGQgdGhlIE9MUyBwcmVkaWN0aW9uIG9uIHRoaXMgZ3JhcGgsIGFuZCBsZXQncyByZXBvcnQgdGhlIHJlZ3Jlc3Npb24gcmVzdWx0LgoKYGBge3J9CnppcGZyZWcgPC0gbG0obG9nLnJhbmsgfiBsb2cucG9wdWxhdGlvbi4yMDE1LCBkYXRhID0gdXMuZHRhKQpzdW1tYXJ5KHppcGZyZWcpCmBgYAoKYGBge3J9CnBsb3QobG9nLnJhbmsgfiBsb2cucG9wdWxhdGlvbi4yMDE1LCBkYXRhID0gdXMuZHRhLCBtYWluID0gIkEgdGVzdCBvZiBaaXBmJ3MgbGF3IGZvciBVLlMuIE1ldHJvIEFyZWFzIiwKICAgICB4bGFiID0gJzIwMTUgTWV0cm8gYXJlYSBwb3B1bGF0aW9uJywgeWxhYiA9ICdsb2coUmFuayknKQphYmxpbmUoemlwZnJlZywgbHdkID0gMywgY29sPSdyZWQnKQpgYGAKCkludGVyZXN0aW5nbHksIHdoaWxlIEdhYmFpeCAoMTk5OSkgYW5kIEtydWdtYW4gKDE5OTYpIHJlcG9ydCBhIGNvZWZmaWNpZW50IG9mIDEsIHRoZSBjb2VmZmljaWVudCB3ZSBvYnRhaW4gaGVyZSBpcyBhYm91dCAwLjksIGNsb3NlIHRvIDEgYnV0IG5vdCBxdWl0ZSAxLiBXaGF0IGlzIHN0cmlraW5nIGhvd2V2ZXIgaXMgX2hvdyB3ZWxsIHRoZSByZWxhdGlvbnNoaXAgcHJlZGljdHMgY2l0eSBzaXplXy4gQSBSIFNxdWFyZWQgb2YgOTglIGlzIGhhcmQgdG8gZmluZCBpbiBlY29ub21pY3MuIAoKV2hpbGUgdGhlIHJlbGF0aW9uc2hpcCBwZXJmb3JtcyB3ZWxsIGZvciB0aGUgbWlkZGxlIG9mIHRoZSBkaXN0cmlidXRpb24gKG1ldHJvIGFyZWFzIHN1Y2ggYXMgTmV3IE9ybGVhbnMgYW5kIFNhbHQgTGFrZSBDaXR5KSwgaXQgcGVyZm9ybXMgbGVzcyB3ZWxsIGZvciB0aGUgbGFyZ2VzdCBtZXRyb3MgKE5ldyBZb3JrKSwgYnV0IHByZXR0eSBiYWRseSBhdCB0aGUgYm90dG9tIG9mIHRoZSBkaXN0cmlidXRpb24gKG1ldHJvIGFyZWFzIHN1Y2ggYXMgUm9tZSwgR0EsIG9yIEZhaXJiYW5rcywgQUspLiBHYWJhaXggKDE5OTkpIHByb3ZpZGVzIGFuIGV4cGxhbmF0aW9uIGJhc2VkIG9uIHRoZSBncmVhdGVyIHZhcmlhbmNlIG9mIGluZHVzdHJ5LWxldmVsIHNob2NrcyBpbiB0aG9zZSBzbWFsbGVyIG1ldHJvcy4KCkdhYmFpeCAoMTk5OSkgY29uc2lkZXJlZCBvbmx5IDEzNSBtZXRyb3MuIEhvdyB3ZWxsIGRvZXMgWmlwZiBsYXcgcGVyZm9ybSB3aXRoIHN1Y2ggYSBzYW1wbGU/IExldCdzIHRyeS4KCmBgYHtyfQp6aXBmcmVnLmxhcmdlc3QgPC0gbG0obG9nLnJhbmsgfiBsb2cucG9wdWxhdGlvbi4yMDE1LCBkYXRhID0gdXMuZHRhWzE6MTM1LF0pCnN1bW1hcnkoemlwZnJlZy5sYXJnZXN0KQpgYGAKCldlIGdldCBhbG1vc3QgdGhlIHNhbWUgcmVzdWx0IGFzIEdhYmFpeCAoMTk5OSkgISBHb29kIHRvIHNlZSB0aGF0IHJlc3VsdHMgY2FuIGJlIHJlcGxpY2F0ZWQuIFRoZSBjb25zdGFudCBpcyBzaWduaWZpY2FudGx5IGhpZ2hlciB0aGFuIGluIGhpcyBwYXBlciB0aG91Z2ggKDEwLjUzIGluIHRoZSBwYXBlciB2cy4gMTcuOTkgaGVyZSkgYnV0IHRoZSBzbG9wZSBpcyBub3Qgc3RhdGlzdGljYWxseSBkaWZmZXJlbnQgZnJvbSAxICgtMS4wMSB3aXRoIGEgc3RhbmRhcmQgZXJyb3Igb2YgMC4wMSkuCgoKYGBge3J9CnBsb3QobG9nLnJhbmsgfiBsb2cucG9wdWxhdGlvbi4yMDE1LCBkYXRhID0gdXMuZHRhWzE6MTM1LF0sIG1haW4gPSAiQSB0ZXN0IG9mIFppcGYncyBsYXcgZm9yIFUuUy4gTWV0cm8gQXJlYXMiLAogICAgIHhsYWIgPSAnMjAxNSBNZXRybyBhcmVhIHBvcHVsYXRpb24nLCB5bGFiID0gJ2xvZyhSYW5rKScpCmFibGluZSh6aXBmcmVnLmxhcmdlc3QsIGx3ZCA9IDMsIGNvbD0ncmVkJykKYGBgCgojIENpdHkgR3Jvd3RoIGFuZCBTdGVhZHktU3RhdGUgQ2l0eSBTaXplIERpc3RyaWJ1dGlvbgoKV2UncmUgZ29pbmcgdG8gbG9vayBhdCB0aGUgdHlwZSBvZiBncm93dGggcHJvY2Vzc2VzIHRoYXQgY2FuIGV4cGxhaW4gWmlwZidzIGxhdy4gRm9yIHRoYXQsIHdlJ3JlIGdvaW5nIHRvIHRha2UgdGhlIGVxdWF0aW9ucyBvZiBHYWJhaXggYW5kIHNpbXVsYXRlIGNpdHkgc2l6ZXMgYXQgZGlmZmVyZW50IHRpbWUgaG9yaXpvbnMgKGEgZmV3IHllYXJzLCBhIGZldyBkZWNhZGVzKSB0byBzZWU6IChpKSB3aGF0IGdyb3d0aCBwcm9jZXNzZXMgKCRmKFxnYW1tYSkkKSBjYW4gZXhwbGFpbiB0aGUgYy5kLmYuIG9mIGNpdHkgc2l6ZXMgYW5kIChpaSkgaG93IG1hbnkgcGVyaW9kcyAkdCQgYXJlIHJlcXVpcmVkIHRvIGdldCBhIGRpc3RyaWJ1dGlvbiB0aGF0IGlzIG5vdCBzdGF0aXN0aWNhbGx5IGRpZmZlcmVudCBmcm9tIFppcGYuCgpgYGB7cn0KTiA8LSAyMDAgIyB3ZSBzdGFydCB3aXRoIDIwMCBjaXRpZXMKVCA8LSAxMDAwICMgYW5kIDEwMCB5ZWFycwoKZ2V0Lm5leHQuZGlzdHJpYnV0aW9uIDwtIGZ1bmN0aW9uKGRpc3QsIG1lYW4sIHNkKSB7CgogIGZvciAoayBpbiAxOmxlbmd0aChkaXN0KSkgewogICAgZGlzdFtrXSA8LSBtYXgoZGlzdFtrXSAqIHJub3JtKDEsIG1lYW4sIHNkKSwgMTAwMCkKICB9CiAgCiAgZGlzdAogICAgCn0KCm5vcm1hbGl6ZS5kaXN0cmlidXRpb24gPC0gZnVuY3Rpb24oZGlzdCkgewogIAogIGRpc3QgPC0gZGlzdCAvIHN1bShkaXN0KQogIAp9CgptYWtlLnppcGYuZHRhIDwtIGZ1bmN0aW9uKGRpc3QpIHsKICAKICBkdGEgPC0gZGF0YS5mcmFtZShwb3B1bGF0aW9uID0gZGlzdFtvcmRlcihkaXN0LCBkZWNyZWFzaW5nPVRSVUUpXSwKICAgICAgICAgICAgIHJhbmsgICAgICAgPSAxOmxlbmd0aChkaXN0KSkKICAKICBkdGEkbG9nLnBvcCA8LSBsb2coZHRhJHBvcHVsYXRpb24pCiAgZHRhJGxvZy5yYW5rIDwtIGxvZyhkdGEkcmFuaykKICAKICBkdGEKICAKfQoKZGlzdHJpYnV0aW9ucyA8LSBjKCkKZGlzdHJpYnV0aW9uc1tbMV1dIDwtIHJub3JtKE4sMSwxMCkqMTAwMDAgKyAxMDAwMAoKZm9yIChrIGluIDI6VCkgewogIGRpc3RyaWJ1dGlvbnNbW2tdXSA8LSBnZXQubmV4dC5kaXN0cmlidXRpb24oZGlzdHJpYnV0aW9uc1tbay0xXV0sIDEsIDAuMSkKfQoKemlwZi5kdGEgPC0gbWFrZS56aXBmLmR0YShkaXN0cmlidXRpb25zW1tUXV0pCgpwbG90KGxvZy5yYW5rIH4gbG9nLnBvcCwgZGF0YSA9IHppcGYuZHRhLCBtYWluID0gJ01vbnRlIENhcmxvIFNpbXVsYXRpb24gLS0gR2licmF0XCdzIGxhdyBhbmQgWmlwZlwncyBsYXcnLAogICAgIHhsYWIgPSAnbG9nKFBvcHVsYXRpb24pJywgeWxhYiA9ICdsb2coUmFuayknKQp6aXBmcmVnIDwtIGxtKGxvZy5yYW5rIH4gbG9nLnBvcCwgZGF0YSA9IHppcGYuZHRhKQphYmxpbmUoemlwZnJlZywgbHdkID0gMywgY29sID0gJ3JlZCcpCgpgYGAKCmBgYHtyfQpzdW1tYXJ5KHppcGZyZWcpCmBgYAoKIyBBZ2dyZWdhdGlvbiBpc3N1ZXMKCmBgYHtyfQpldXJvcGVkdGEgPC0gcmVhZHhsOjpyZWFkX2V4Y2VsKCdFdXJvcGVhbi1tZXRyb3BvbGl0YW4tYXJlYXMueGxzeCcpCmV1cm9wZWR0YSA8LSB0cmFuc2Zvcm0oZXVyb3BlZHRhLAogICAgICAgICAgICAgICAgICAgICAgIGxvZy5yYW5rID0gbG9nKGFzLm51bWVyaWMoYFJhbmtgKSksCiAgICAgICAgICAgICAgICAgICAgICAgbG9nLnBvcCAgPSBsb2coYXMubnVtZXJpYyhwb3B1bGF0aW9uKSkpIApwbG90KGxvZy5yYW5rIH4gbG9nLnBvcCwgZGF0YSA9IGV1cm9wZWR0YSkKZXVyb3BlcmVnIDwtIGxtKGxvZy5yYW5rIH4gbG9nLnBvcCwgZGF0YSA9IGV1cm9wZWR0YSkKYWJsaW5lKGV1cm9wZXJlZywgbHdkPTMsIGNvbD0ncmVkJykKYGBgCgpgYGB7cn0Kc3VtbWFyeShldXJvcGVyZWcpCmBgYAoK