Skip to content

The aim of this project is to use R to investigate whether there is evidence of the Phillips curve in the Malaysian economy based on annual data from 1982 to 2019. Inflation and unemployment datasets from the Malaysian Department of Statistics are used for this project.

The Phillips curve describes the negative correlation between the inflation rate and the unemployment rate. (1)

MODEL 1: Basic Phillips Curve

The first model used to estimate the relationship between the inflation rate and the unemployment rate is a basic model defined as \pi_t=\ u_t+\ \varepsilon, where \pi_t = the inflation rate in period t, u_t = the unemployment rate in period t, and \varepsilon = the error term.

Figure 1 shows a downward sloping line, suggesting the existence of the Phillips curve in Malaysia from 1982 to 2019. However, we cannot conclude that the Phillips curve exists from this alone as there are variables other than the unemployment rate that might explain the inflation rate. Besides that, the relationship between the inflation rate and the unemployment rate might not be negative in different time periods, as seen in the breakdown of the Phillips curve in the US in the 1970s. (2)

Figure 2 illustrates the trajectory of the relationship between the inflation rate and the unemployment rate in a chronological order, highlighted by decade and crisis years. The years 1985-1986, 1997-1998, and 2008-2009 are highlighted for the 1985-1986 Malaysian recession, the 1997 Asian Financial Crisis, and the 2008 financial crisis. Note that the 1980s had the greatest variation in the unemployment rate. On the other hand, in the 2000s and the 2010s, the unemployment rate changed within a smaller range compared to the changes in the inflation rate. Besides that, the inflation rate was relatively stable from 1993 to 1996 prior to the Asian Financial Crisis even though the unemployment rate fell during those years.

Figure 3 shows various best fit lines for the relationship between the inflation rate and the unemployment rate. While a negative correlation between the inflation rate and unemployment rate in the 1980s, the 2000s, and the 2010s. The line for the 1990s is upward sloping and nearly flat.

The table below summarises the regression results of Model 1 for the overall period and each decade.

Note that R squared is generally low, with most of the R squared values being less than 0.1, suggesting that the model does not fit the data that well. The R squared value is the highest when the model is tested using the 1980s data, at 0.632.

The coefficient for the unemployment rate estimates how much a 1 percentage point increase in the unemployment rate changes the inflation rate. The coefficient is negative for the overall period and all decades other than the 1990s. It is the largest in absolute value when the model is tested using the 2010s data. It is only statistically significant at 5% level when the model is tested using the 1980s data.

While Model 1 is a basic model with only one independent variable, the number of observations is too low when it is tested by decade.

MODEL 2: Adaptive expectations Phillips curve

Model 2 extends Model 1 by adding expected inflation as a variable that explains the inflation rate. In the adaptive expectations framework, workers use the inflation period in the preceeding period to revise their expectations in response to their forecasting errors. (3)

It is defined as \pi_t=\ \pi_{t-1}\ +\ u_t+\ \varepsilon, where \pi_t = the inflation rate in period t, \pi_{t-1} = the inflation rate in period t-1, u_t = the unemployment rate in period t, and \varepsilon = the error term.

As in Model 1, the coefficient for the unemployment rate is negative but its absolute value is smaller in Model 2 than in Model 1. The coefficient for the lagged inflation rate estimates how much a 1 percentage point increase in the inflation rate in the previous year increases the inflation rate in the current year. It is significant at 5% level.

Note that the R squared value in Model 2 is higher than in Model 1, suggesting that Model 2 fits the data better than Model 1. Figures 4 and 5 illustrate this. While inflation rates predicted by Model 1 broadly track the movement of actual inflation rates from 1982 to the middle of the 1990s, they then remain relatively flat despite significant increases and decreases in the actual inflation rates.

In contrast, inflation rates predicted by Model 2 track the movement of actual rates better but delayed, as expected from the inclusion of lagged inflation rates.

MODEL 3: Exchange rates as supply shocks

Model 3 extends Model 2 by adding the exchange rate as a supply shock that affects the inflation rate. Malaysia is an open economy, so a depreciated Malaysian ringgit makes imports more expensive, hence increasing prices.

The model is defined as \pi_t=\ \pi_{t-1}\ +\ u_t+E_t+\ \varepsilon, where \pi_t = the inflation rate in period t, \pi_{t-1} = the inflation rate in period t-1, u_t = the unemployment rate in period t, E_t + the exhange rate in period t, and \varepsilon = the error term.

The exchange rate is represented by the average annual exchange rate of Malaysian ringgit per US dollar in Model 3a and by the average annual nominal effective exchange rate (NEER) in Model 3b.

Spinner
DataFrameas
df
variable
[1]
-- Explore the data in the table
SELECT *
FROM 'lfs_year.csv'
LIMIT 5
Spinner
DataFrameas
df
variable
[2]
-- Explore the data in the table
SELECT *
FROM 'cpi_2d_annual_inflation.csv'
LIMIT 5
#The codes used are documented here for reference. R codes cannot be run in this environment.

#Loading packages
library(readr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(ggrepel)
library(lubridate)
library(zoo)
library(mFilter)
library(texreg)

#Import data
unemployment <- read_csv("C:/Users/USER/Desktop/R/lfs_year.csv")
inflation <- read_csv("C:/Users/USER/Desktop/R/cpi_2d_annual_inflation.csv")
USD_MYR <- read_csv("C:/Users/USER/Desktop/R/USD_MYR.csv")
NEER <- read_csv("C:/Users/USER/Desktop/R/NEER.csv")
GDP <- read_csv("C:/Users/USER/Desktop/R/gdp_gni_annual_real.csv")

#Transforming unemployment dataframe
unemployment <- unemployment %>% select(date, u_rate) %>% mutate(year = year(date))

#Transforming inflation dataframe
inflation <- inflation %>% filter(division == "overall") %>% mutate(year = year(date))

#Creating a new dataframe for unemployment and inflation
inf_unm <- unemployment %>% full_join(inflation, by = "year")
inf_unm <- inf_unm %>% select(year, u_rate, inflation)
inf_unm <- inf_unm %>% arrange(year) %>% mutate(u_rate = na.approx(u_rate, na.rm = FALSE))
inf_unm <- inf_unm %>% arrange(year) %>% mutate(lagged_inflation = lag(inflation, 1))
inf_unm <- inf_unm %>% filter(year >= 1982 & year <= 2019)
inf_unm <- inf_unm %>% mutate(decade = floor(year / 10) * 10)
inf_unm <- inf_unm %>% mutate(decade = factor(decade,
                                              levels = c(1980, 1990, 2000, 2010),
                                              labels = c("1980s", "1990s", "2000s", "2010s")))
inf_unm <- inf_unm %>% select(year,decade,u_rate,inflation,lagged_inflation)

#Assigning label years and decade colours for visualisation
label_years <- c(1982, 1985, 1986, 1989, 1990, 1997, 1998,1999, 2000, 2008, 2009,2010,2019)
decade_colors <- c("1980s" = "cyan", "1990s" = "deeppink", "2000s" = "darkgoldenrod1", "2010s" = "darkgreen")

#Plotting a Phillips curve
phillipscurve <- ggplot(inf_unm, aes(x = u_rate, y = inflation)) +
  geom_point(
    color = "darkgreen",
    size = 3,
    alpha = 0.7
  ) +
  geom_smooth(
    method = "lm",
    color = "orange",
    linetype = "dashed"
  ) +
  labs(
    x = "Unemployment Rate (%)",
    y = "Inflation Rate (%)",
    title = "Figure 1: The Phillips Curve in Malaysia, 1982–2019"
  ) +
  scale_x_continuous(limits = c(0, NA)) +
  scale_y_continuous(limits = c(0, NA)) +
  coord_fixed() +
  theme_light() +
  theme(
    plot.title = element_text(
      hjust = 0.5,
      size = 16,
      face = "bold"
    )
  )

#Plotting the trajectory of the relationship between unemployment rate and inflation by decade
trajectory <- ggplot(
  inf_unm,
  aes(x = u_rate, y = inflation, color = decade, group = decade)
) +
  geom_path(size = 1) +
  geom_point(size = 2) +
  geom_text_repel(
    data = subset(inf_unm, year %in% label_years),
    aes(label = year),
    vjust = -0.6,
    show.legend = FALSE
  ) +
  scale_color_manual(values = decade_colors) +
  labs(
    x = "Unemployment rate (%)",
    y = "Inflation rate (%)",
    color = "Decade",
    title = "Figure 2: Trajectory of Inflation–Unemployment Relationship in Malaysia, 1982-2019"
  ) +
  scale_x_continuous(limits = c(0, NA)) +
  scale_y_continuous(
    limits = c(0, NA),
    expand = expansion(mult = c(0.05, 0.15))
  ) +
  coord_fixed() +
  theme_minimal() +
  theme(
    plot.margin = margin(t = 15, r = 10, b = 10, l = 10)
  )

#Plotting a Phillips curve for each decade
phillipscurve_decade <- ggplot(
  inf_unm,
  aes(x = u_rate, y = inflation, color = decade)
) +
  geom_point(size = 2) +
  geom_smooth(method = "lm", se = FALSE) +
  scale_color_manual(values = decade_colors) +
  labs(
    x = "Unemployment rate (%)",
    y = "Inflation rate (%)",
    color = "Decade",
    title = "Figure 3: The Phillips Curve in Malaysia by Decade, 1982-2019"
  ) +
  scale_x_continuous(limits = c(0, NA)) +
  scale_y_continuous(limits = c(0, NA)) +
  coord_fixed() +
  theme_minimal()

#Testing the basic model over the total period and by decade
model1 <- lm(inflation ~ u_rate, data = inf_unm)
model1_1980s <- inf_unm %>%
                  filter(decade == "1980s") %>%
                  lm(inflation ~ u_rate, data = .)
model1_1990s <- inf_unm %>%
                  filter(decade == "1990s") %>%
                  lm(inflation ~ u_rate, data = .)
model1_2000s <- inf_unm %>%
                  filter(decade == "2000s") %>%
                  lm(inflation ~ u_rate, data = .)
model1_2010s <- inf_unm %>%
                  filter(decade == "2010s") %>%
                  lm(inflation ~ u_rate, data = .)

#Creating a table for Model 1 results
screenreg(list(model1, model1_1980s, model1_1990s,model1_2000s,model1_2010s),
                    custom.model.names = c("1982-2019","1980s", "1990s", "2000s", "2010s"),
                    custom.coef.names = c("Intercept","Unemployment rate"),
                    digits = 3)

#Testing Model 2
model2 <- lm(inflation ~ u_rate + lagged_inflation, data = inf_unm)

#Creating a table for Model 2 results
screenreg(list(model1, model2), digits = 3, file = "table2.txt")

#Creating a dataframe with inflation rates predicted by Model 1 and Model 2
inf_unm_predict <- inf_unm %>% arrange(year) %>% mutate(inflation_model1 = predict(model1)) %>% mutate(inflation_model2 = predict(model2))

#Plotting actual inflation rates and inflation rates predicted by Model 1
label_years_2 <- c(1985, 1986, 1997, 1998, 2008, 2009)
figure4 <- ggplot(inf_unm_predict, aes(x = year)) +
  geom_line(aes(y = inflation, color = "Actual"), linewidth = 1,) +
  geom_line(aes(y = inflation_model1, color = "Predicted"), linewidth = 1,) +
  geom_text_repel(
    data = subset(inf_unm_predict, year %in% label_years_2),
    aes(y = inflation, label = year),
    color = "blue",
    size = 4,
    min.segment.length = 0
  ) +
  labs(
    x = "Year",
    y = "Inflation rate (%)",
    color = "",
    title = "Figure 4: Actual vs Predicted Inflation Rates - Model 1"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Predicted" = "red")
  ) +
  theme_minimal()

#Plotting actual inflation rates and inflation rates predicted by Model 2
figure5 <- ggplot(inf_unm_predict, aes(x = year)) +
  geom_line(aes(y = inflation, color = "Actual"), linewidth = 1,) +
  geom_line(aes(y = inflation_model2, color = "Predicted"), linewidth = 1,) +
  geom_text_repel(
    data = subset(inf_unm_predict, year %in% label_years_2),
    aes(y = inflation, label = year),
    color = "blue",
    size = 4,
    min.segment.length = 0
  ) +
  labs(
    x = "Year",
    y = "Inflation rate (%)",
    color = "",
    title = "Figure 5: Actual vs Predicted Inflation Rates - Model 2"
  ) +
  scale_color_manual(
    values = c("Actual" = "black", "Predicted" = "red")
  ) +
  theme_minimal()

REFERENCES

  1. Labor Economics, Borjas, pg 533
  2. Labor Economics, Borjas, pg 533
  3. Macroeconomics: Institutions, Instability, and the Financial System, Carlin & Soskice, pg 127