Проект R, исследующий регрессии с фиксированными эффектами
Введение
Экономическая теория говорит нам, что производительность труда является основным фактором, определяющим заработную плату. Однако многие критики предполагают, что эти отношения нарушились, особенно в последние десятилетия. Этот проект исследует регрессию с фиксированными эффектами для анализа связи между производительностью и заработной платой в группе стран ОЭСР.
Этот проект не претендует на то, чтобы быть всесторонним, а скорее представляет собой эксперимент, который предоставляет некоторые данные по этой теме из разных стран.
Источники данных
Все мои данные будут поступать в базу данных ОЭСР. Я загружаю три ряда данных в файлах CSV: производительность труда (ВВП за отработанный час), среднегодовая заработная плата и среднегодовое отработанное время. Я беру период времени с 1990 по 2018 год, так как это наибольшее количество данных, доступных из всех трех наборов данных.
Полный код и наборы данных доступны на моем Github здесь.
Проект
Во-первых, я переношу каждый набор данных в R. Я также загружаю пару стандартных пакетов, которые использую практически в любом проекте, за который берусь.
library(ggplot2) library(dplyr) #Bring in labour productivity data GDPh <- read.csv("DP_LIVE_16062020201012437.csv") #Bring in average annual wages Wage <- read.csv("DP_LIVE_16062020201639206.csv") #Bring in average annual hours worked Hours <- read.csv("DP_LIVE_16062020202140847.csv")
Очистка и подготовка данных
Как обычно почти для любого проекта, данные будут поступать именно в том виде, в котором мы хотим. Данные ОЭСР хорошо структурированы, но все еще требуют некоторой работы, чтобы получить их в нужном формате. Для каждого ряда данных я переименую пару столбцов для удобства чтения, а затем удалю столбцы, которые мне не нужны.
#GDP per hour names(GDPh)[1] <- "Country" names(GDPh)[7] <- "GDP.h" GDPh <- GDPh[-c(2:5,8)] #Annual wages names(Wage)[1] <- "Country" names(Wage)[7] <- "Wage" Wage <- Wage[-c(2:5,8)] #Hours worked per year names(Hours)[1] <- "Country" names(Hours)[7] <- "Hours.a" Hours <- Hours[-c(2:5,8)]
Отсюда я могу объединить наборы данных в один фрейм данных:
Comb <- merge(GDPh, Hours) Comb <- merge(Comb, Wage)
Этот набор данных включает ОЭСР в целом как страну, которую я не хочу включать (поскольку я смотрю на отдельные страны). Мне нужно удалить эти наблюдения из моих данных. Этого можно добиться несколькими способами, но я нашел изящный способ создать функцию «не внутри», которую легко использовать в данном случае.
#Create 'notin' function `%notin%` <- Negate(`%in%`) #Remove OECD observations Comb <- subset(Comb, Country %notin% c("OECD"))
Наконец, я хочу создать новый столбец, содержащий среднюю почасовую заработную плату, а не среднюю годовую заработную плату, которая у меня есть прямо сейчас. Для этого я могу просто разделить столбец «Зарплата» на столбец «Часы.a», чтобы создать новый столбец.
#Create an hourly wage column Comb$H_wage <- Comb$Wage/Comb$Hours.a
На данный момент данные находятся в формате, с которым я могу работать.
Статистика
Обычные наименьшие квадраты
Для начала давайте просто создадим стандартную регрессию методом наименьших квадратов (OLS) с данными:
#OLS regression ols <- lm(H_wage~GDP.h, Comb) summary(ols)
Сводка затем обеспечивает следующий вывод:
Коэффициент 0,466 (означающий, что на каждый доллар повышения производительности труда заработная плата увеличивается на 0,466 доллара) является статистически значимым.
Мы также можем визуализировать эту регрессию. Хотя я мог бы использовать функцию построения графика по умолчанию, большинство людей считают пакет ggplot более привлекательным.
library(ggplot2) #Visualize fit ggplot(Comb, aes(x=GDP.h, y=H_wage)) + geom_point() + geom_smooth(method=lm) + labs(x = "GDP Per Hour Worked", y = "Hourly Wage")
Что производит следующий сюжет:
Однако из-за неоднородности стран это не лучший способ анализа данных.
Балансировка панели
Первым шагом будет проверка сбалансированности панели (это означает, что у нас одинаковые периоды времени для всех стран). Я уже знаю, что панель несбалансирована, но мы все равно покажем код. Для этого воспользуемся пакетом «plm».
library(plm) is.pbalanced(Comb) [1] FALSE
Эта функция подтвердила, что наша панель несбалансирована. К счастью, этот пакет также имеет функцию балансировки нашей панели. Однако мы должны выбрать, как сбалансировать нашу панель (функция предоставляет три варианта). Я выберу вариант, который сохраняет все доступные периоды времени, исключая страны, для которых они недоступны.
length(unique(Comb$Country)) [1] 35
Этот фрагмент кода говорит мне, что моя панель в настоящее время имеет 35 стран.
Comb <- make.pbalanced(Comb, balance.type = "shared.individuals") length(unique(Comb$Country)) [1] 15
В новом наборе данных теперь всего 15 стран, что значительно меньше выборки стран. Подтверждение сбалансированности новой панели:
is.pbalanced(Comb) [1] TRUE
Теперь панель сбалансирована. Теперь я создам визуализацию стран на оставшейся панели.
ggplot(Comb, aes(x=GDP.h, y=H_wage)) + geom_point() + facet_wrap(.~ Country, scales = "free") + labs(title = "Country Panel", caption = "Source: OECD", y = "Average Wage", x = "GDP/Hour Worked")
Модель фиксированных эффектов
Теперь мы можем запустить модель с фиксированными эффектами на нашей панели.
f <- plm(H_wage~GDP.h, data=Comb, model="within") summary(f)
Что производит следующий вывод:
Коэффициент теперь равен 0,486 и по-прежнему является статистически значимым. Мы можем построить график, показывающий регрессию внутри страны:
plot(f, pooling=F, within=T)
Хотя на нашей панели слишком много стран для создания визуально привлекательного графика, это может быть полезно для наборов данных с меньшим количеством объектов. Тем не менее, мы все еще можем видеть, что практически все страны демонстрируют положительную взаимосвязь.
Тестирование модели с фиксированными эффектами на МНК
Во-первых, я повторно запускаю OLS на сбалансированном наборе данных. Теперь мы можем протестировать модель с фиксированными эффектами в сравнении с МНК, чтобы увидеть, лучше ли она объясняет данные:
#Test fixed-effects against OLS pFtest(f, ols)
Мы можем отвергнуть нулевую гипотезу; модель с фиксированными эффектами дает результаты, которые значительно лучше, чем МНК.
Диагностика модели
Я проверю, есть ли у модели фиксированные по времени эффекты.
#Time fixed effects ft <- plm(H_wage ~ GDP.h + factor(TIME), data=Comb, model="within") summary(ft)
#Test time-fixed effects--null hypothesis is no time fixed effects pFtest(ft,f)
Р-значение 0,029 затруднительно — оно дает хорошие, но не убедительные доказательства фиксированных во времени эффектов. Это говорит о том, что эта модель может быть более подходящей.
Другая диагностика
Хотя я не буду выполнять их здесь, есть множество других тестов, которые вы можете выполнить. Особую озабоченность вызывает перекрестная зависимость. Вы также можете проверить серийную корреляцию и гетероскедастичность.