Rの関数 ur.ers {urca} のスクラッチ再現を試みます。
本ポストはこちらの続きです。

Rの関数:ur.ers {urca}
Rの関数から ur.ers {urca} を確認します。本ポストはこちらの続きです。ur.ers関数についてur.ersは、エリオット–ローゼンバーグ–ストック(Elliot, Rothenberg, and Stock, ERS)検定 を...
ur.ers(type=“DF-GLS”, model=“trend”) のスクラッチ再現コード
# ============================================================
# ur.ers(type="DF-GLS", model="trend") のスクラッチ再現コード
# (Elliott, Rothenberg, and Stock (1996) の DF-GLS 検定)
# ============================================================
library(urca)
# -------------------------------
# (1) データ生成
# -------------------------------
<- 20251017
seed set.seed(seed)
<- 100 # サンプルサイズ
T <- 0.95 # AR(1) 系列の係数(単位根に近い)
phi <- rnorm(T) # ホワイトノイズ
e <- numeric(T)
y for (t in 2:T) y[t] <- phi * y[t - 1] + e[t] # y_t = phi * y_{t-1} + e_t
# -------------------------------
# (2) ur.ers() によるERS単位根検定
# -------------------------------
<- ur.ers(y, type = "DF-GLS", model = "trend", lag.max = 4)
ur_out
<- ur_out@teststat # t値(DF-GLS統計量)
urca_t <- ur_out@lag # ur.ersが自動選択したラグ数
lag_used
# ============================================================
# (3) ur.ers() の理論構造に基づくスクラッチ実装
# ============================================================
# -------------------------------
# 3-1. GLS 前処理:局所デトレンド
# -------------------------------
# Elliott et al. (1996) では、GLSデトレンドのために
# (1 - a_hat * L) で前処理を行う。
# a_hat = 1 - c/T
# - c = 13.5(モデルに定数+トレンドを含む場合)
# - c = 7(モデルが定数のみの場合)
# ur.ers() ではこの規則を採用している。
# ------------------------------------------------------------
<- 1 - 13.5 / T
ahat <- 1:T # 時間トレンド
trd
# y_t のGLS変換: y_t^a = y_t - a_hat * y_{t-1} (ただし先頭はそのまま)
<- c(y[1], y[2:T] - ahat * y[1:(T - 1)])
ya
# 定数項・トレンド項も同様にGLS変換
<- c(1, rep(1 - ahat, T - 1)) # 定数項(1)
za1 <- c(1, trd[2:T] - ahat * trd[1:(T - 1)]) # トレンド項(t)
za2
# -------------------------------
# 3-2. GLS回帰による定数除去(デトレンド)
# -------------------------------
# ya = β1 * za1 + β2 * za2 + u_t
# 切片を含めず回帰(-1)とする理由:
# za1, za2が既に「定数項・トレンド項」として設計されているため。
# ------------------------------------------------------------
<- lm(ya ~ -1 + za1 + za2)
yd.reg
# 推定された β1, β2 を使って y からトレンドを除去
<- coef(yd.reg)
coef_hat <- y - coef_hat[1] - coef_hat[2] * trd
yd # → これが GLS デトレンド済み系列(ur.ers内部の "detrended series")
# -------------------------------
# 3-3. DF-GLS 検定用のADF回帰を構築
# -------------------------------
# Δyd_t = ρ * yd_{t-1} + Σ γ_i * Δyd_{t-i} + ε_t
# の回帰を行い、ρ の t値をDF-GLS統計量とする。
# ------------------------------------------------------------
<- yd[1:(T - 1)] # 遅行系列 yd_{t-1}
yd.l <- diff(yd) # 差分系列 Δyd_t
yd.diff <- lag_used # ur.ers()が自動選択したラグ数を使用
p
if (p > 0) {
# embed() によりラグ項行列を作成
# embed(diff(yd), p+1) の結果は Δyd_t, Δyd_{t-1}, …, Δyd_{t-p}
# ここから Δyd_t(最初の列)を除いた部分を説明変数として使用
<- embed(diff(yd), p + 1)[, -1]
yd.dlags
# データフレーム整形
<- data.frame(
data.dfgls yd.diff = yd.diff[-(1:p)], # 先頭p観測を除外
yd.l = yd.l[-(1:p)], # 遅行系列(整列)
yd.dlags
)colnames(data.dfgls)[-(1:2)] <- paste0("yd.diff.lag", 1:p)
# 回帰式: Δyd_t ~ yd_{t-1} + Δyd_{t-1} + … + Δyd_{t-p} (切片なし)
<- as.formula(paste(
dfgls.form "yd.diff ~ -1 +", paste(colnames(data.dfgls)[-1], collapse = "+")
))else {
} # ラグなしADF
<- data.frame(yd.diff = yd.diff, yd.l = yd.l)
data.dfgls <- yd.diff ~ -1 + yd.l
dfgls.form
}
# -------------------------------
# 3-4. OLS回帰と統計量抽出
# -------------------------------
<- summary(lm(dfgls.form, data = data.dfgls))
dfgls.reg <- coef(dfgls.reg)[1, 3] # yd_{t-1} の t値が検定統計量
scratch_t
# -------------------------------
# (4) 結果比較
# -------------------------------
cat("スクラッチ実装により求めた検定統計量 t:", scratch_t, "\n")
cat("関数ur.ers()により求めた検定統計量 t:", urca_t, "\n")
cat("両者は一致しているか:", all.equal(scratch_t, urca_t), "\n")
スクラッチ実装により求めた検定統計量 t: -1.482571
関数ur.ers()により求めた検定統計量 t: -1.482571
両者は一致しているか: TRUE
続いて、生成したサンプル時系列データ(Original y)とトレンド除去後の時系列データ(GLS_detrended_yd)を比較します。
library(ggplot2)
<- data.frame(
df_plot t = 1:T,
y = y,
yd = yd
)
ggplot(df_plot, aes(x = t)) +
geom_line(aes(y = y, color = "Original y"), linewidth = 0.5) +
geom_line(aes(y = yd, color = "GLS-detrended yd"), linewidth = 0.5) +
scale_color_manual(values = c("Original y" = "steelblue", "GLS-detrended yd" = "tomato")) +
labs(
title = "DF-GLS (trend model): 生成データとトレンド除去後のデータの比較",
x = "Time", y = "Value", color = ""
+
) theme_minimal(base_size = 14) +
theme(legend.position = "top")
ur.ers(type=“DF-GLS”, model=“constant”) のスクラッチ再現コード
# ============================================================
# ur.ers(type="DF-GLS", model="constant") のスクラッチ再現コード
# Elliott, Rothenberg, and Stock (1996) のDF-GLS検定
# ============================================================
# -------------------------------
# (1) データ生成
# -------------------------------
# 先に生成したサンプル時系列データ y を利用。
# -------------------------------
# (2) ur.ers() によるERS単位根検定
# -------------------------------
<- ur.ers(y, type = "DF-GLS", model = "constant", lag.max = 4)
ur_out
<- ur_out@teststat # DF-GLS統計量(t値)
urca_t <- ur_out@lag # 自動選択されたラグ数
lag_used
# ============================================================
# (3) ur.ers() の理論構造に基づくスクラッチ実装
# ============================================================
# -------------------------------
# 3-1. GLSデトレンド準備
# -------------------------------
# Elliott et al. (1996) の提案では、GLS変換係数 a_hat は:
# a_hat = 1 - c / T
# - model="constant" の場合: c = 7
# - model="trend" の場合: c = 13.5
# ur.ers() もこの値を採用している。
# ------------------------------------------------------------
<- 1 - 7 / T # 定数項モデルでは c = 7
ahat
# GLS変換を行う:
# y_t^a = y_t - a_hat * y_{t-1} (ただし先頭はそのまま)
<- c(y[1], y[2:T] - ahat * y[1:(T - 1)])
ya
# 定数項(1)のGLS変換:
# z_t^a = 1 - a_hat * 1 = 1 - a_hat
# ただし t = 1 の場合は 1 とする
<- c(1, rep(1 - ahat, T - 1))
za1
# -------------------------------
# 3-2. GLS回帰による定数除去(デトレンド)
# -------------------------------
# ya = β1 * za1 + u_t
# (切片なし回帰:-1を指定)
# ------------------------------------------------------------
<- lm(ya ~ -1 + za1)
yd.reg
# 推定された β1 を使って元系列 y から定数成分を除去
<- coef(yd.reg)
coef_hat <- y - coef_hat[1]
yd # → これが「GLSデトレンド済み系列(DF-GLS系列)」に相当
# -------------------------------
# 3-3. DF-GLS 検定用のADF回帰を構築
# -------------------------------
# DF-GLSの検定回帰式:
# Δyd_t = ρ * yd_{t-1} + Σ γ_i * Δyd_{t-i} + ε_t
# ------------------------------------------------------------
<- yd[1:(T - 1)] # yd_{t-1}
yd.l <- diff(yd) # Δyd_t
yd.diff <- lag_used # ur.ersが選択したラグ数
p
if (p > 0) {
# Δyd のラグ項を生成(embedで時系列行列を作成)
<- embed(diff(yd), p + 1)[, -1]
yd.dlags
# データ整形
<- data.frame(
data.dfgls yd.diff = yd.diff[-(1:p)],
yd.l = yd.l[-(1:p)],
yd.dlags
)colnames(data.dfgls)[-(1:2)] <- paste0("yd.diff.lag", 1:p)
# 回帰式を動的に構築
<- as.formula(paste(
dfgls.form "yd.diff ~ -1 +", paste(colnames(data.dfgls)[-1], collapse = "+")
))else {
} # ラグなしADF
<- data.frame(yd.diff = yd.diff, yd.l = yd.l)
data.dfgls <- yd.diff ~ -1 + yd.l
dfgls.form
}
# -------------------------------
# 3-4. OLS回帰と統計量抽出
# -------------------------------
<- summary(lm(dfgls.form, data = data.dfgls))
dfgls.reg <- coef(dfgls.reg)[1, 3] # yd_{t-1} の t値を抽出
scratch_t
# -------------------------------
# (4) 結果比較
# -------------------------------
cat("スクラッチ実装により求めた検定統計量 t:", scratch_t, "\n")
cat("関数ur.ers()により求めた検定統計量 t:", urca_t, "\n")
cat("両者は一致しているか:", all.equal(scratch_t, urca_t), "\n")
スクラッチ実装により求めた検定統計量 t: -1.465639
関数ur.ers()により求めた検定統計量 t: -1.465639
両者は一致しているか: TRUE
続いて、生成したサンプル時系列データ(Original y)とトレンド除去後の時系列データ(GLS_detrended_yd)を比較します。
<- data.frame(
df_plot t = 1:T,
y = y,
yd = yd
)
ggplot(df_plot, aes(x = t)) +
geom_line(aes(y = y, color = "Original y"), linewidth = 0.5) +
geom_line(aes(y = yd, color = "GLS-detrended yd"), linewidth = 0.5) +
scale_color_manual(values = c("Original y" = "steelblue", "GLS-detrended yd" = "tomato")) +
labs(
title = "DF-GLS (constant model): 生成データとトレンド除去後のデータの比較",
x = "Time", y = "Value", color = ""
+
) theme_minimal(base_size = 14) +
theme(legend.position = "top")
以上です。