Chapter 2. The Heckscher-Ohlin Model”

In these exercises, you will reproduce some of the empirical results from Trefler (1993, 1995). To complete the exercise, the Excel file hov_pub.csv should be stored in the directory: c:\Empirical_Exercise\Chapter_2\hov_pub.csv. After this, run the STATA program hov_pub.do, which will create a new STATA data file trefler.dta.

Read and transform the data

Feenstra’s code

* This is to read the data into Stata *

set mem 30m
* insheet using c:\Empirical_Exercise\Chapter_2\trefler.csv *
insheet using "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\hov_pub.csv"
rename v1 country
rename v2 factor
rename v3 AT
rename v4 V
rename v5 Y
rename v6 B
rename v7 YPC
rename v8 POP

* create country index *
quietly summarize YPC
local maxYPC=_result(6)
gen ratio=YPC/`maxYPC'
replace ratio=ratio+0.0001 if country=="Italy"

sort ratio
egen indexc=group(ratio)

* create factor index *
sort factor
egen indexf=group(factor)

* include delta *

gen delta=1
replace delta=0.03 if country=="Bangladesh"
replace delta=0.09 if country=="Pakistan"
replace delta=0.10 if country=="Indonesia"
replace delta=0.09 if country=="Sri Lanka"
replace delta=0.17 if country=="Thailand"
replace delta=0.16 if country=="Colombia"
replace delta=0.28 if country=="Panama"
replace delta=0.29 if country=="Yugoslavia"
replace delta=0.14 if country=="Portugal"
replace delta=0.11 if country=="Uruguay"
replace delta=0.45 if country=="Greece"
replace delta=0.55 if country=="Ireland"
replace delta=0.42 if country=="Spain"
replace delta=0.49 if country=="Israel"
replace delta=0.40 if country=="Hong Kong"
replace delta=0.38 if country=="New Zealand"
replace delta=0.60 if country=="Austria"
replace delta=0.48 if country=="Singapore"
replace delta=0.60 if country=="Italy"
replace delta=0.58 if country=="UK"
replace delta=0.70 if country=="Japan"
replace delta=0.65 if country=="Belgium"
replace delta=0.47 if country=="Trinidad"
replace delta=0.72 if country=="Netherlands"
replace delta=0.65 if country=="Finland"
replace delta=0.73 if country=="Denmark"
replace delta=0.78 if country=="West Germany"
replace delta=0.74 if country=="France"
replace delta=0.57 if country=="Sweden"
replace delta=0.69 if country=="Norway"
replace delta=0.79 if country=="Switzerland"
replace delta=0.55 if country=="Canada"
replace delta=1 if country=="USA"

compress

label var country "Name of the country"
label var factor "Name of the factor"
label var AT "Factor content of trade F=A*T"
label var V "Endowment"
label var Y "GDP, World Bank, y=p*Q"
label var B "Trade balance, World Bank b=p*T"
label var YPC "GDP per capita, PWT"
label var indexc "Country indentifier"
label var indexf "Factor Indentifier"

* save c:\Empirical_Exercise\Chapter_2\trefler,replace *
save "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\trefler", replace

exit

My code

# Packages ----

library(archive)
library(readr)
library(dplyr)
library(tidyr)
library(purrr)
library(knitr)

# Extract ----

fzip <- "first-edition/Chapter-2.zip"
dout <- gsub("\\.zip$", "", fzip)

if (!dir.exists(dout)) {
  archive_extract("first-edition/Chapter-2.zip",
    dir = "first-edition/Chapter-2"
  )
}

# Read ----

fout <- paste0(dout, "/trefler.rds")
fout2 <- paste0(dout, "/trefler_desc.rds")

if (!file.exists(fout)) {
  trefler <- read_csv("first-edition/Chapter-2/hov_pub.csv", col_names = F) %>%
    rename(
      country = X1,
      factor = X2,
      at = X3,
      v = X4,
      y = X5,
      b = X6,
      ypc = X7,
      pop = X8
    )

  # Transform ----

  # see https://www.stata.com/manuals/rsummarize.pdf
  # https://www.stata.com/manuals/degen.pdf
  # https://www.stata.com/manuals/degen.pdf

  # Create an auxiliary table for delta values
  delta_values <- tibble(
    country = c(
      "Bangladesh", "Pakistan", "Indonesia", "Sri Lanka", "Thailand",
      "Colombia", "Panama", "Yugoslavia", "Portugal", "Uruguay", "Greece",
      "Ireland", "Spain", "Israel", "Hong Kong", "New Zealand", "Austria",
      "Singapore", "Italy", "UK", "Japan", "Belgium", "Trinidad", "Netherlands",
      "Finland", "Denmark", "West Germany", "France", "Sweden", "Norway",
      "Switzerland", "Canada", "USA"
    ),
    delta = c(
      0.03, 0.09, 0.10, 0.09, 0.17, 0.16, 0.28, 0.29, 0.14, 0.11, 0.45,
      0.55, 0.42, 0.49, 0.40, 0.38, 0.60, 0.48, 0.60, 0.58, 0.70, 0.65, 0.47,
      0.72, 0.65, 0.73, 0.78, 0.74, 0.57, 0.69, 0.79, 0.55, 1
    )
  )

  trefler <- trefler %>%
    mutate(ypc_max = max(ypc)) %>%
    mutate(
      ratio = case_when(
        country != "Italy" ~ ypc / ypc_max,
        country == "Italy" ~ (ypc / ypc_max) + 0.0001
      )
    ) %>%
    select(-ypc_max) %>%
    arrange(ratio) %>%
    group_by(ratio) %>%
    mutate(indexc = cur_group_id()) %>%
    group_by(factor) %>%
    mutate(indexf = cur_group_id()) %>%
    ungroup() %>%
    left_join(delta_values)

  # Labels ----

  # Create a separate table with the variables description

  trefler_desc <- tibble(
    variable = c(
      "country", "factor", "at", "v", "y", "b", "ypc", "indexc",
      "indexf"
    ),
    description = c(
      "Name of the country", "Name of the factor",
      "Factor content of trade F=A*T", "Endowment", "GDP, World Bank, y=p*Q",
      "Trade balance, World Bank b=p*T", "GDP per capita, PWT",
      "Country indentifier", "Factor Indentifier"
    )
  )

  # Save ----

  saveRDS(trefler, fout)
  saveRDS(trefler_desc, fout2)
} else {
  trefler <- readRDS(fout)
  trefler_desc <- readRDS(fout2)
}

Exercise 1

Given identical technologies across countries, run the program sign_rank_1.do to conduct the sign test, rank test, and test for missing trade. Use the results in sign_rank_1.log to replicate columns (2) and (4) in Table 2.5.

Feenstra’s code

* This program is to conduct sign test, Rank test and Missing trade test *

capture log close
* log using c:\Empirical_Exercise\Chapter_2\sign_rank_1.log, replace *
log using "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\sign_rank_1.log", replace

set mem 30m

* use C:\Empirical_Exercise\Chapter_2\trefler, clear *
use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\trefler", clear

* number of country in the dataset *
egen C=max(indexc)
egen F=max(indexf)

* Calculate the world level of Yw, Bw and Vw *
egen Yww=sum(Y)
gen Yw=Yww/F
egen Bww=sum(B)
gen Bw=Bww/F
egen Vfw=sum(V), by(indexf)

* Calculate country share Sc *
gen Sc=(Y-B)/(Yw-Bw)

* Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)*
gen Efc=AT-(V-Sc*Vfw)

* Construct the average epsilon for a given factor *
egen total=sum(Efc),by(indexf)
gen ave=total/C

* Construct sigma^2 and the weight *

egen tot=sum((Efc-ave)^2), by(indexf)
gen sigma2f=tot/(C-1)

codebook sigma2f
gen sigmaf=sqrt(sigma2f)
gen weight=sigmaf*sqrt(Sc)

* Using the weight, convert all the data *

gen trAT=AT/(sigmaf*sqrt(Sc))
gen trV=V/(sigmaf*sqrt(Sc))
gen trY=Y/sqrt(Sc)
gen trB=B/sqrt(Sc)
gen trVfw=Vfw/sigmaf

gen AThat=trV-Sc*trVfw
gen AThat2=(V-Sc*Vfw)/weight

* Correlation, should be .28 *

corr trAT AThat2

*************
* Sign Test *
*************

sort indexc
by indexc: count if trAT*AThat2>0

count if trAT*AThat2>0
display _result(1)/_N

*****************
* Missing Trade *
*****************

* Checking for the missing trade, should be .032 *

quietly summarize trAT
local varAT=_result(4)
quietly summarize AThat
local varHat=_result(4)
quietly summarize AThat2
local varHat2=_result(4)
display `varAT'/`varHat'
display `varAT'/`varHat2'

**************
* Rank Tests *
**************

keep country indexc indexf trAT AThat2

sort indexc indexf
reshape wide trAT AThat2, i(indexc) j(indexf)

local i=1
while `i'<9{
    local j=`i'+1
    while `j'<=9{
        gen rank`i'`j'=((trAT`i'-trAT`j')*(AThat2`i'-AThat2`j')>0)
        local j=`j'+1
    }
    local i=`i'+1
}

keep country indexc rank*
reshape long rank, i(indexc) j(factor)
egen r1=sum(rank), by(indexc)
gen r2=r1/36
collapse r2,by(indexc country)
sum r2
list

log close
exit

My code

# Transform ----

trefler <- readRDS(fout) %>%
  # Number of country in the dataset
  mutate(
    c = max(indexc),
    f = max(indexf)
  ) %>%
  # Calculate the world level of Yw, Bw and Vw
  mutate(
    yww = sum(y),
    yw = yww / f,
    bww = sum(b),
    bw = bww / f
  ) %>%
  group_by(indexf) %>%
  mutate(
    vfw = sum(v)
  ) %>%
  ungroup() %>%
  # Calculate country share Sc
  mutate(
    sc = (y - b) / (yw - bw)
  ) %>%
  # Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)
  mutate(
    efc = at - (v - sc * vfw)
  ) %>%
  # Construct the average epsilon for a given factor
  group_by(indexf) %>%
  mutate(ave = sum(efc) / c) %>%
  # Construct sigma^2 and the weight
  mutate(
    sigma2f = sum((efc - ave)^2) / (c - 1),
    sigmaf = sqrt(sigma2f),
    weight = sigmaf * sqrt(sc)
  ) %>%
  ungroup() %>%
  # Using the weight, convert all the data
  mutate(
    trat = at / (sigmaf * sqrt(sc)),
    athat2 = (v - (sc * vfw)) / weight
  ) %>%
  arrange(country)

# Correlation, should be .28
trefler %>%
  select(trat, athat2) %>%
  cor()
            trat    athat2
trat   1.0000000 0.2822883
athat2 0.2822883 1.0000000
# Sign Test ----

trefler %>%
  group_by(country, indexc) %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  )
# A tibble: 33 × 3
# Groups:   country [33]
   country    indexc     p
   <chr>       <int> <dbl>
 1 Austria        17 0.556
 2 Bangladesh      1 0.333
 3 Belgium        22 0.667
 4 Canada         32 0.556
 5 Colombia        6 0.333
 6 Denmark        26 0.444
 7 Finland        25 0.333
 8 France         28 0.333
 9 Greece         11 0.111
10 Hong Kong      15 0.667
# ℹ 23 more rows
trefler %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  )
# A tibble: 1 × 1
      p
  <dbl>
1 0.498
# Missing Trade ----

# Checking for the missing trade, should be .032

trefler %>%
  summarize(
    varat = var(trat),
    varhat2 = var(athat2)
  ) %>%
  mutate(
    varat_varhat2 = varat / varhat2
  )
# A tibble: 1 × 3
  varat varhat2 varat_varhat2
  <dbl>   <dbl>         <dbl>
1  1.61    50.3        0.0320
# Rank Tests ----

trefler_wide <- trefler %>%
  select(country, indexc, indexf, trat, athat2) %>%
  arrange(indexc, indexf) %>%
  pivot_wider(
    names_from = indexf,
    values_from = c(trat, athat2)
  )

# This would be too long
# trefler_wide <- trefler_wide %>%
#   mutate(
#     rank12 = (trat_1 - trat_2) * (athat2_1 - athat2_2) > 0,
#     rank13 = (trat_1 - trat_3) * (athat2_1 - athat2_3) > 0,
#     ...
#     rank89 = (trat_8 - trat_9) * (athat2_8 - athat2_9) > 0,
#   )

# create all relevant trat_1 - trat_2, trat_1 - trat_3, etc.

ranks <- expand_grid(
  x = 1:8,
  y = 1:9
) %>%
  filter(x < y)

# The syntax here is based on internal R developer functions, but these
# allow to create columns with minimal lines of code and avoids more complicated
# bracket syntax
trefler_rank <- map2_df(
  pull(ranks, x),
  pull(ranks, y),
  function(x, y) {
    trefler_wide %>%
      mutate(
        name = paste0("rank", x, y),
        value = (!!sym(paste0("trat_", x)) - !!sym(paste0("trat_", y))) *
          (!!sym(paste0("athat2_", x)) - !!sym(paste0("athat2_", y))) > 0
      ) %>%
      select(country, indexc, name, value)
  }
) %>%
  group_by(country, indexc) %>%
  summarise(r1 = sum(value)) %>%
  mutate(r2 = r1 / 36)

trefler_rank
# A tibble: 33 × 4
# Groups:   country [33]
   country    indexc    r1     r2
   <chr>       <int> <int>  <dbl>
 1 Austria        17    19 0.528 
 2 Bangladesh      1    27 0.75  
 3 Belgium        22    22 0.611 
 4 Canada         32    32 0.889 
 5 Colombia        6    29 0.806 
 6 Denmark        26    19 0.528 
 7 Finland        25    17 0.472 
 8 France         28     3 0.0833
 9 Greece         11    17 0.472 
10 Hong Kong      15    30 0.833 
# ℹ 23 more rows
trefler_rank %>%
  pull(r2) %>%
  mean()
[1] 0.6026936

Extra step: formatting the table

trefler %>%
  group_by(country, indexc) %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  ) %>%
  arrange(indexc) %>% # same order as in the book
  select(country, sign_hov = p) %>%
  left_join(
    trefler_rank %>%
      select(country, rank_hov = r2)
  ) %>%
  bind_rows(
    trefler %>%
      summarize(
        p = sum(trat * athat2 > 0) / n()
      ) %>%
      mutate(
        country = "All countries",
        rank_hov = mean(pull(trefler_rank, r2))
      ) %>%
      select(country, sign_hov = p, rank_hov)
  ) %>%
  mutate_if(is.numeric, round, 2) %>% # same no of decimals as in the book
  kable()
country sign_hov rank_hov
Bangladesh 0.33 0.75
Pakistan 0.33 0.72
Indonesia 0.22 0.67
Sri Lanka 0.22 0.42
Thailand 0.22 0.69
Colombia 0.33 0.81
Panama 0.33 0.56
Yugoslavia 0.56 0.44
Portugal 0.22 0.53
Uruguay 1.00 0.72
Greece 0.11 0.47
Ireland 0.67 0.53
Spain 0.22 0.39
Israel 0.67 0.39
Hong Kong 0.67 0.83
New Zealand 0.44 0.53
Austria 0.56 0.53
Singapore 0.56 0.61
Italy 0.67 0.78
UK 0.67 0.58
Japan 0.78 0.78
Belgium 0.67 0.61
Trinidad 0.67 0.50
Netherlands 0.44 0.53
Finland 0.33 0.47
Denmark 0.44 0.53
West Germany 0.56 0.81
France 0.33 0.08
Sweden 0.44 0.67
Norway 0.44 0.61
Switzerland 0.89 0.56
Canada 0.56 0.89
USA 0.89 0.92
All countries 0.50 0.60

Exercise 2

Given uniform technological differences across countries, run the program sign_rank_2.do to redo the sign test, rank test, and missing trade. Use the results in sign_rank_2.log to replicate column (3) and (5), given column (6) in Table 2.5.

Feenstra’s code

* This program is to conduct sign test, Rank test and Missing trade test *
* using delta *

capture log close
* log using c:\Empirical_Exercise\Chapter_2\sign_rank_2.log, replace *
log using "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\sign_rank_2.log", replace

set mem 30m

* use c:\Empirical_Exercise\Chapter_2\trefler, clear *
use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\trefler", clear

* number of country in the dataset *
egen C=max(indexc)
egen F=max(indexf)

* Calculate the world level of Yw, Bw and Vw *
egen Yww=sum(Y)
gen Yw=Yww/F
egen Bww=sum(B)
gen Bw=Bww/F
egen Vfw=sum(V), by(indexf)
egen Vw=sum(delta*V), by(indexf)

* Calculate country share Sc *
gen Sc=(Y-B)/(Yw-Bw)

* Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)

gen Efc=delta*AT-(delta*V-Sc*Vw)

* Construct the average epsilon for a given factor *
egen total=sum(Efc),by(indexf)
gen ave=total/C

* Construct sigma^2 and the weight *

egen tot=sum((Efc-ave)^2), by(indexf)
gen sigma2f=tot/(C-1)

codebook sigma2f
gen sigmaf=sqrt(sigma2f)
gen weight=sigmaf*sqrt(Sc)

* Using the weight, convert all the data *

gen trAT=delta*AT/weight
gen AThat2=(delta*V-Sc*Vw)/weight

* Correlation *

corr trAT AThat2

*************
* Sign Test *
*************

sort indexc
by indexc: count if trAT*AThat2>0

count if trAT*AThat2>0
display _result(1)/_N

*****************
* Missing Trade *
*****************

quietly summarize trAT
local varAT=_result(4)
quietly summarize AThat
local varHat=_result(4)
quietly summarize AThat2
local varHat2=_result(4)
display `varAT'/`varHat'
display `varAT'/`varHat2'

*************
* Rank Test *
*************

keep country indexc indexf trAT AThat2

sort indexc indexf
reshape wide trAT AThat2, i(indexc) j(indexf)

local i=1
while `i'<9{
    local j=`i'+1
    while `j'<=9{
        gen rank`i'`j'=((trAT`i'-trAT`j')*(AThat2`i'-AThat2`j')>0)
        local j=`j'+1
    }
    local i=`i'+1
}

keep country indexc rank*
reshape long rank, i(indexc) j(factor)
egen r1=sum(rank), by(indexc)
gen r2=r1/36
collapse r2,by(indexc country)
sum r2
list

log close
exit

My code

# Transform ----

trefler <- readRDS(fout) %>%
  # Number of country in the dataset
  mutate(
    c = max(indexc),
    f = max(indexf)
  ) %>%
  # Calculate the world level of Yw, Bw and Vw
  mutate(
    yww = sum(y),
    yw = yww / f,
    bww = sum(b),
    bw = bww / f
  ) %>%
  group_by(indexf) %>%
  mutate(
    vfw = sum(v),
    vw = sum(delta * v)
  ) %>%
  ungroup() %>%
  # Calculate country share Sc
  mutate(
    sc = (y - b) / (yw - bw)
  ) %>%
  # Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)
  mutate(
    efc = delta * at - (delta * v - sc * vw)
  ) %>%
  # Construct the average epsilon for a given factor
  group_by(indexf) %>%
  mutate(ave = sum(efc) / c) %>%
  # Construct sigma^2 and the weight
  mutate(
    sigma2f = sum((efc - ave)^2) / (c - 1),
    sigmaf = sqrt(sigma2f),
    weight = sigmaf * sqrt(sc)
  ) %>%
  ungroup() %>%
  # Using the weight, convert all the data
  mutate(
    trat = delta * at / weight,
    athat2 = (delta * v - (sc * vw)) / weight
  )

# Correlation should be .41
trefler %>%
  select(trat, athat2) %>%
  cor()
            trat    athat2
trat   1.0000000 0.4099617
athat2 0.4099617 1.0000000
# Sign Test ----

trefler %>%
  group_by(country, indexc) %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  )
# A tibble: 33 × 3
# Groups:   country [33]
   country    indexc     p
   <chr>       <int> <dbl>
 1 Austria        17 0.667
 2 Bangladesh      1 0.778
 3 Belgium        22 0.778
 4 Canada         32 0.222
 5 Colombia        6 0.889
 6 Denmark        26 0.444
 7 Finland        25 0.444
 8 France         28 0.333
 9 Greece         11 0.556
10 Hong Kong      15 0.889
# ℹ 23 more rows
trefler %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  )
# A tibble: 1 × 1
      p
  <dbl>
1 0.620
# Missing Trade ----

# Checking for the missing trade, should be .07

trefler %>%
  summarize(
    varat = var(trat),
    varhat2 = var(athat2)
  ) %>%
  mutate(
    varat_varhat2 = varat / varhat2
  )
# A tibble: 1 × 3
  varat varhat2 varat_varhat2
  <dbl>   <dbl>         <dbl>
1  1.34    19.0        0.0706
# Rank Tests ----

trefler_wide <- trefler %>%
  select(country, indexc, indexf, trat, athat2) %>%
  arrange(indexc, indexf) %>%
  pivot_wider(
    names_from = indexf,
    values_from = c(trat, athat2)
  )

ranks <- expand_grid(
  x = 1:8,
  y = 1:9
) %>%
  filter(x < y)

trefler_rank <- map2_df(
  pull(ranks, x),
  pull(ranks, y),
  function(x, y) {
    trefler_wide %>%
      mutate(
        name = paste0("rank", x, y),
        value = (!!sym(paste0("trat_", x)) - !!sym(paste0("trat_", y))) *
          (!!sym(paste0("athat2_", x)) - !!sym(paste0("athat2_", y))) > 0
      ) %>%
      select(country, indexc, name, value)
  }
) %>%
  group_by(country, indexc) %>%
  summarise(r1 = sum(value)) %>%
  mutate(r2 = r1 / 36)

trefler_rank
# A tibble: 33 × 4
# Groups:   country [33]
   country    indexc    r1    r2
   <chr>       <int> <int> <dbl>
 1 Austria        17    16 0.444
 2 Bangladesh      1    28 0.778
 3 Belgium        22    19 0.528
 4 Canada         32    20 0.556
 5 Colombia        6    31 0.861
 6 Denmark        26    15 0.417
 7 Finland        25    18 0.5  
 8 France         28     7 0.194
 9 Greece         11    27 0.75 
10 Hong Kong      15    26 0.722
# ℹ 23 more rows
trefler_rank %>%
  pull(r2) %>%
  mean()
[1] 0.6153199

Extra step: formatting the table

trefler %>%
  group_by(country, indexc) %>%
  summarize(
    p = sum(trat * athat2 > 0) / n()
  ) %>%
  arrange(indexc) %>% # same order as in the book
  select(country, sign_hov = p) %>%
  left_join(
    trefler_rank %>%
      select(country, rank_hov = r2)
  ) %>%
  bind_rows(
    trefler %>%
      summarize(
        p = sum(trat * athat2 > 0) / n()
      ) %>%
      mutate(
        country = "All countries",
        rank_hov = mean(pull(trefler_rank, r2))
      ) %>%
      select(country, sign_hov = p, rank_hov)
  ) %>%
  mutate_if(is.numeric, round, 2) %>% # same no of decimals as in the book
  kable()
country sign_hov rank_hov
Bangladesh 0.78 0.78
Pakistan 0.67 0.78
Indonesia 0.67 0.67
Sri Lanka 0.56 0.67
Thailand 0.67 0.72
Colombia 0.89 0.86
Panama 0.78 0.78
Yugoslavia 0.67 0.61
Portugal 0.78 0.58
Uruguay 0.11 0.53
Greece 0.56 0.75
Ireland 0.44 0.39
Spain 0.78 0.69
Israel 0.89 0.69
Hong Kong 0.89 0.72
New Zealand 0.22 0.61
Austria 0.67 0.44
Singapore 1.00 0.61
Italy 0.33 0.67
UK 0.78 0.64
Japan 0.67 0.78
Belgium 0.78 0.53
Trinidad 1.00 0.53
Netherlands 0.44 0.47
Finland 0.44 0.50
Denmark 0.44 0.42
West Germany 0.67 0.78
France 0.33 0.19
Sweden 0.44 0.36
Norway 0.44 0.78
Switzerland 0.89 0.50
Canada 0.22 0.56
USA 0.56 0.72
All countries 0.62 0.62

Notes

The Stata code that I run returns the same values as R. However:

  • Austria should have values 0.67 and 0.47. I got 0.67 and 0.44.
  • France should have values 0.33 and 0.22. I got 0.33 and 0.19.
  • Switzerland should have values 0.89 and 0.47. I got 0.89 and 0.50.

Exercise 3

Allowing all factors in each country to have different productivities, now run the program compute_pi.do to compute factor productivities \(\pi_k^i\) as Trefler (1993). Note that there are 9 factors in the original data set, but these are now aggregated to just 4 factors, which are labor (endowment 1), capital (endowment 2), cropland (endowment 3) and pasture (endowment 4). Using the results in pi_.log or alternatively in the data files pi_1.dta, pi_2.dta, pi_3.dta, pi_4.dta to answer the following:

  1. Which factor has the most negative productivities estimated?
  2. What is the correlation between the estimated labor productivity and the productivities of other factors? What is the correlation between each factor productivity and GDP per-capita (which you can find in the file trefler.dta)?

Feenstra’s code

* This program is to compute pai, the factor productivity *

capture log close
* log using c:\Empirical_Exercise\Chapter_2\pi.log,replace *
log using "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\pi.log", replace

set mem 30m

* use c:\Empirical_Exercise\Chapter_2\trefler, clear *
use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\trefler", clear

* number of country in the dataset *
egen C=max(indexc)
egen F=max(indexf)

* Calculate the world level of Yw, Bw and Vw *
egen Yww=sum(Y)
gen Yw=Yww/F
egen Bww=sum(B)
gen Bw=Bww/F
egen Vfw=sum(V), by(indexf)

* Calculate country share Sc *
gen Sc=(Y-B)/(Yw-Bw)

* Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)
gen Efc=AT-(V-Sc*Vfw)

* Construct the average epsilon for a given factor *
egen total=sum(Efc),by(indexf)
gen ave=total/C

* Construct sigma^2 and the weight *

egen tot=sum((Efc-ave)^2), by(indexf)
gen sigma2f=tot/(C-1)

codebook sigma2f
gen sigmaf=sqrt(sigma2f)
gen weight=sigmaf*sqrt(Sc)

* Using the weight, convert all the data *

gen trAT=AT/(sigmaf*sqrt(Sc))
gen trV=V/(sigmaf*sqrt(Sc))
gen trY=Y/sqrt(Sc)
gen trB=B/sqrt(Sc)
gen trVfw=Vfw/sigmaf

gen AThat=trV-Sc*trVfw
gen AThat2=(V-Sc*Vfw)/weight

* Construct Aggregate Labor Endowment *

preserve
keep if indexf==7 |indexf==8 | indexf==9
gen en=2
replace en=3 if indexf==8
replace en=4 if indexf==9
keep country factor AT V en indexc Sc

* save c:\Empirical_Exercise\Chapter_2\indexf_189,replace *
save "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\indexf_189", replace

restore

preserve
drop if indexf==7 |indexf==8 | indexf==9

egen v_l=sum(V), by(country)
egen AT_l=sum(AT), by(country)

drop V AT factor
rename v_l V
rename AT_l AT
gen en=1
collapse (mean)AT V en indexc Sc, by(country)
gen str5 factor="Labor"
* save c:\Empirical_Exercise\Chapter_2\indexf_L,replace *
save "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\indexf_L", replace

restore

* use c:\Empirical_Exercise\Chapter_2\indexf_189,clear *
use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\indexf_189", clear

* append using c:\Empirical_Exercise\Chapter_2\indexf_L *
append using "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\indexf_L"
sort indexc en
* save c:\Empirical_Exercise\Chapter_2\pi,replace *
save "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\pi", replace

************************************
* Compute Pi: factor productivity *
************************************

* use c:\Empirical_Exercise\Chapter_2\pi, clear *
use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\pi", clear

gen p_0=1
gen p_1=1

local i=1
while `i'<=4{
    preserve
    keep if en==`i'
    local j=1
    while `j'<51{
        replace p_0=p_1
        gen Vp=p_0*V
        egen Vpw=sum(Vp)
        replace p_1=(AT+Sc*Vpw)/V
        replace p_1=1 if country=="USA"
        drop Vp Vpw
        local j=`j'+1
    }
    keep en country indexc p_1
    * save c:\Empirical_Exercise\Chapter_2\pi_`i',replace *
  save "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\pi_`i'", replace
    restore
    local i=`i'+1
}

local i=1
while `i'<=4{
    * use c:\Empirical_Exercise\Chapter_2\pi_`i',clear *
  use "Z:\home\pacha\github\advanced-international-trade\first-edition\Chapter-2\pi_`i'", clear
    sort en indexc
    by en: list en indexc country p_1
    local i=`i'+1
}

log close

exit

My code

trefler <- readRDS(fout) %>%
  # Number of country in the dataset
  mutate(
    c = max(indexc),
    f = max(indexf)
  ) %>%
  # Calculate the world level of Yw, Bw and Vw
  mutate(
    yww = sum(y),
    yw = yww / f,
    bww = sum(b),
    bw = bww / f
  ) %>%
  group_by(indexf) %>%
  mutate(
    vfw = sum(v),
    vw = sum(delta * v)
  ) %>%
  ungroup() %>%
  # Calculate country share Sc
  mutate(
    sc = (y - b) / (yw - bw)
  ) %>%
  # Calculate epsilon(fc) and sigma^2(f) according to eq.2 in Trefler (1995)
  mutate(
    efc = delta * at - (delta * v - sc * vw)
  ) %>%
  # Construct the average epsilon for a given factor
  group_by(indexf) %>%
  mutate(ave = sum(efc) / c) %>%
  # Construct sigma^2 and the weight
  mutate(
    sigma2f = sum((efc - ave)^2) / (c - 1),
    sigmaf = sqrt(sigma2f),
    weight = sigmaf * sqrt(sc)
  ) %>%
  ungroup() %>%
  # Using the weight, convert all the data
  mutate(
    trat = delta * at / weight,
    athat2 = (delta * v - (sc * vw)) / weight
  )

# No need to save changes and restore
trefler2 <- trefler %>%
  # Construct Aggregate Labor Endowment
  filter(indexf %in% 7:9) %>%
  mutate(
    en = case_when(
      indexf == 7 ~ 2,
      indexf == 8 ~ 3,
      indexf == 9 ~ 4
    )
  ) %>%
  select(country, factor, indexf, at, v, en, indexc, sc)

trefler3 <- trefler %>%
  filter(!(indexf %in% 7:9)) %>%
  group_by(country) %>%
  # No need to create v_l and at_l to then rename and then collapse
  summarise(
    v = sum(v),
    at = sum(at),
    sc = mean(sc),
    indexc = mean(indexc)
  ) %>%
  mutate(
    en = 1,
    factor = "Labor"
  )

trefler3 <- trefler2 %>%
  select(-indexf) %>%
  bind_rows(trefler3) %>%
  arrange(indexc, en)

# Compute Pi: factor productivity
# No need to save intermediate outputs, we proceed with iteration
trefler4 <- map_df(
  trefler3 %>%
    distinct(en) %>%
    pull(),
  function(x) {
    d <- trefler3 %>%
      filter(en == x) %>%
      mutate(p0 = 1, p1 = 1)

    iter <- 50

    for (i in seq_len(iter)) {
      d <- d %>%
        mutate(
          p0 = p1,
          vp = p0 * v,
          vpw = sum(vp),
          p1 = ifelse(country == "USA", 1, (at + sc * vpw) / v)
        ) %>%
        select(-vp, -vpw)
    }

    # Tidy alternative to the for loop
    # d <- accumulate(seq_len(iter), .init = d, ~ .x %>%
    #   mutate(
    #     p0 = p1,
    #     p1 = ifelse(country == "USA", 1, (at + sc * sum(p1 * v)) / v)
    #   )) %>%
    #   .[[iter + 1]]

    d %>%
      select(country, indexc, en, p1)
  }
)

Extra step: formatting the tables

trefler4 %>%
  arrange(country, en) %>%
  kable()
country indexc en p1
Austria 17 1 0.5694186
Austria 17 2 0.5421980
Austria 17 3 1.1596592
Austria 17 4 1.9753040
Bangladesh 1 1 0.0165219
Bangladesh 1 2 0.9119021
Bangladesh 1 3 0.0230836
Bangladesh 1 4 1.2561775
Belgium 22 1 0.7233988
Belgium 22 2 0.6457500
Belgium 22 3 0.4575561
Belgium 22 4 6.8868596
Canada 32 1 0.7799865
Canada 32 2 0.7359194
Canada 32 3 0.4738445
Canada 32 4 0.9541137
Colombia 6 1 0.1940833
Colombia 6 2 0.4856291
Colombia 6 3 0.5963939
Colombia 6 4 0.1271541
Denmark 26 1 0.7061784
Denmark 26 2 0.7035640
Denmark 26 3 1.7598990
Denmark 26 4 28.7283398
Finland 25 1 0.6969619
Finland 25 2 0.6453199
Finland 25 3 0.6789600
Finland 25 4 22.2966445
France 28 1 0.7356650
France 28 2 0.6150762
France 28 3 1.5589519
France 28 4 3.1663974
Greece 11 1 0.3140718
Greece 11 2 0.4401574
Greece 11 3 0.6072472
Greece 11 4 0.5059134
Hong Kong 15 1 0.3781684
Hong Kong 15 2 0.5150965
Hong Kong 15 3 -229.0729738
Hong Kong 15 4 -879.5376414
Indonesia 3 1 0.0432824
Indonesia 3 2 0.2506530
Indonesia 3 3 0.1641388
Indonesia 3 4 0.4576649
Ireland 12 1 0.4166084
Ireland 12 2 0.4783923
Ireland 12 3 1.4803708
Ireland 12 4 0.6129137
Israel 14 1 0.6131932
Israel 14 2 0.5049116
Israel 14 3 2.5171947
Israel 14 4 2.1567210
Italy 19 1 0.5907437
Italy 19 2 0.5122213
Italy 19 3 0.6419316
Italy 19 4 3.1452732
Japan 21 1 0.6049210
Japan 21 2 0.6502130
Japan 21 3 4.2923043
Japan 21 4 100.5984017
Netherlands 24 1 0.7933355
Netherlands 24 2 0.7513015
Netherlands 24 3 9.0914542
Netherlands 24 4 13.0978390
New Zealand 16 1 0.5850298
New Zealand 16 2 0.6197254
New Zealand 16 3 7.5203295
New Zealand 16 4 0.3673216
Norway 30 1 0.7816517
Norway 30 2 0.6199874
Norway 30 3 1.8129219
Norway 30 4 34.5985787
Pakistan 2 1 0.0394124
Pakistan 2 2 0.4867497
Pakistan 2 3 0.0975686
Pakistan 2 4 0.4731917
Panama 7 1 0.2279774
Panama 7 2 0.3224079
Panama 7 3 0.5834955
Panama 7 4 0.2973391
Portugal 9 1 0.1759864
Portugal 9 2 0.2971070
Portugal 9 3 -0.3833130
Portugal 9 4 1.6397757
Singapore 18 1 0.4873306
Singapore 18 2 0.3209652
Singapore 18 3 -25.4922493
Singapore 18 4 795.1006524
Spain 13 1 0.4172726
Spain 13 2 0.5194890
Spain 13 3 0.2365766
Spain 13 4 1.0176692
Sri Lanka 4 1 0.0344433
Sri Lanka 4 2 0.1259789
Sri Lanka 4 3 0.2300838
Sri Lanka 4 4 0.7949096
Sweden 29 1 0.7270576
Sweden 29 2 0.9445322
Sweden 29 3 0.9073509
Sweden 29 4 7.6468612
Switzerland 31 1 0.9317447
Switzerland 31 2 0.6079722
Switzerland 31 3 3.7425295
Switzerland 31 4 3.3350218
Thailand 5 1 0.0489020
Thailand 5 2 0.3929541
Thailand 5 3 0.3002516
Thailand 5 4 16.9392348
Trinidad 23 1 0.4483440
Trinidad 23 2 0.4193396
Trinidad 23 3 -0.9042060
Trinidad 23 4 4.6219780
UK 20 1 0.6332355
UK 20 2 0.8159872
UK 20 3 1.4765402
UK 20 4 2.2422499
USA 33 1 1.0000000
USA 33 2 1.0000000
USA 33 3 1.0000000
USA 33 4 1.0000000
Uruguay 10 1 0.2029693
Uruguay 10 2 0.4060566
Uruguay 10 3 0.5709917
Uruguay 10 4 0.0984165
West Germany 27 1 0.7691833
West Germany 27 2 0.6629313
West Germany 27 3 1.0541740
West Germany 27 4 6.8647780
Yugoslavia 8 1 0.1997569
Yugoslavia 8 2 0.2985477
Yugoslavia 8 3 0.3189656
Yugoslavia 8 4 0.6397429