What is an ARDL Model?

Loading required packages

What is ARDL? Autoregressive Distributed Lag (ARDL) is a time series model used to analyze both short-run and long-run relationships between variables.

Breaking it down Autoregressive(AR) means the dependent variable depends on its own past values.

Distributed Lag (DL) means the dependent variable depends on past values of other variables. The model is ideal for use when there is mix of I(0) and I(1) variables in the data.

Set and confirm the working directory

getwd()
## [1] "C:/Users/Hp/Documents/ARDL"

load the data into the R environment

data <- read.csv("ECON DEVELOPMENT DATA.csv")
# Convert to time series object
# Assuming you have quarterly or monthly data - adjust frequency accordingly
ts_data <- ts(data, start = c(1994, 1), frequency = 1)  # adjust as needed
# Extract variables
ECNDEV <- ts_data[, "ECNDEV"]
INF <- ts_data[, "INF"]
K <- ts_data[, "K"]
L <- ts_data[, "L"]
EDU <- ts_data[, "EDU"]
HEA <- ts_data[, "HEA"]
UNEMP <- ts_data[, "UNEMP"]
# 1. UNIT ROOT TESTS (Stationarity Testing)
cat("\n", "========== UNIT ROOT TESTS ==========", "\n")
## 
##  ========== UNIT ROOT TESTS ==========
# Function to perform multiple unit root tests
unit_root_tests <- function(series, series_name) {
  cat("\n", "-------------------------------------", "\n")
  cat("Testing for:", series_name, "\n")
  cat("-------------------------------------", "\n")
  
  # Remove NAs
  series_clean <- na.omit(series)
  
  # ADF Test
  adf_level <- adf.test(series_clean, alternative = "stationary")
  adf_firstdiff <- adf.test(diff(series_clean), alternative = "stationary")
  
  # Phillips-Perron Test
  pp_level <- pp.test(series_clean)
  pp_firstdiff <- pp.test(diff(series_clean))
  
  # KPSS Test
  kpss_level <- kpss.test(series_clean)
  kpss_firstdiff <- kpss.test(diff(series_clean))
  
  # Results summary
  results <- data.frame(
    Test = c("ADF Level", "ADF First Diff", 
             "PP Level", "PP First Diff",
             "KPSS Level", "KPSS First Diff"),
    Statistic = round(c(adf_level$statistic, adf_firstdiff$statistic,
                        pp_level$statistic, pp_firstdiff$statistic,
                        kpss_level$statistic, kpss_firstdiff$statistic), 4),
    P_Value = round(c(adf_level$p.value, adf_firstdiff$p.value,
                      pp_level$p.value, pp_firstdiff$p.value,
                      kpss_level$p.value, kpss_firstdiff$p.value), 4),
    Result = c(
      ifelse(adf_level$p.value < 0.05, "Stationary", "Non-Stationary"),
      ifelse(adf_firstdiff$p.value < 0.05, "Stationary", "Non-Stationary"),
      ifelse(pp_level$p.value < 0.05, "Stationary", "Non-Stationary"),
      ifelse(pp_firstdiff$p.value < 0.05, "Stationary", "Non-Stationary"),
      ifelse(kpss_level$p.value > 0.05, "Stationary", "Non-Stationary"),
      ifelse(kpss_firstdiff$p.value > 0.05, "Stationary", "Non-Stationary")
    )
  )
  
print(results)
# Determine integration order
  cat("\nConclusion for", series_name, ":")
  if(adf_level$p.value < 0.05 && pp_level$p.value < 0.05 && kpss_level$p.value > 0.05) {
    cat(" I(0) - Stationary at level\n")
  } else if(adf_firstdiff$p.value < 0.05 && pp_firstdiff$p.value < 0.05) {
    cat(" I(1) - Stationary at first difference\n")
  } else {
    cat(" I(2) or higher - Further testing needed\n")
  }
}

# Run unit root tests for all variables
variables <- list(ECNDEV = ECNDEV, INF = INF, K = K, L = L, 
                  EDU = EDU, HEA = HEA, UNEMP = UNEMP)
for(var_name in names(variables)) {
  unit_root_tests(variables[[var_name]], var_name)
}
## 
##  ------------------------------------- 
## Testing for: ECNDEV 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -1.2585  0.8576 Non-Stationary
## 2  ADF First Diff   -2.9932  0.1919 Non-Stationary
## 3        PP Level   -4.2032  0.8647 Non-Stationary
## 4   PP First Diff  -31.7284  0.0100     Stationary
## 5      KPSS Level    0.8693  0.0100 Non-Stationary
## 6 KPSS First Diff    0.3074  0.1000     Stationary
## 
## Conclusion for ECNDEV : I(2) or higher - Further testing needed
## 
##  ------------------------------------- 
## Testing for: INF 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -2.4361  0.4051 Non-Stationary
## 2  ADF First Diff   -4.2036  0.0153     Stationary
## 3        PP Level   -8.0951  0.6079 Non-Stationary
## 4   PP First Diff  -36.6904  0.0100     Stationary
## 5      KPSS Level    0.2843  0.1000     Stationary
## 6 KPSS First Diff    0.2848  0.1000     Stationary
## 
## Conclusion for INF : I(1) - Stationary at first difference
## 
##  ------------------------------------- 
## Testing for: K 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level    0.2420  0.9900 Non-Stationary
## 2  ADF First Diff   -0.3781  0.9807 Non-Stationary
## 3        PP Level    7.3655  0.9900 Non-Stationary
## 4   PP First Diff  -19.8693  0.0290     Stationary
## 5      KPSS Level    0.7927  0.0100 Non-Stationary
## 6 KPSS First Diff    0.6857  0.0148 Non-Stationary
## 
## Conclusion for K : I(2) or higher - Further testing needed
## 
##  ------------------------------------- 
## Testing for: L 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -2.7132  0.2987 Non-Stationary
## 2  ADF First Diff   -1.5153  0.7584 Non-Stationary
## 3        PP Level   -9.8984  0.4889 Non-Stationary
## 4   PP First Diff  -14.3069  0.1952 Non-Stationary
## 5      KPSS Level    0.3606  0.0941     Stationary
## 6 KPSS First Diff    0.1330  0.1000     Stationary
## 
## Conclusion for L : I(2) or higher - Further testing needed
## 
##  ------------------------------------- 
## Testing for: EDU 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -3.3645  0.0810 Non-Stationary
## 2  ADF First Diff   -2.4270  0.4089 Non-Stationary
## 3        PP Level   -3.8646  0.8870 Non-Stationary
## 4   PP First Diff   -9.5376  0.5111 Non-Stationary
## 5      KPSS Level    1.0697  0.0100 Non-Stationary
## 6 KPSS First Diff    0.1316  0.1000     Stationary
## 
## Conclusion for EDU : I(2) or higher - Further testing needed
## 
##  ------------------------------------- 
## Testing for: HEA 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -1.4735  0.7750 Non-Stationary
## 2  ADF First Diff   -3.3139  0.0886 Non-Stationary
## 3        PP Level  -10.4759  0.4508 Non-Stationary
## 4   PP First Diff  -25.0914  0.0100     Stationary
## 5      KPSS Level    1.0075  0.0100 Non-Stationary
## 6 KPSS First Diff    0.1352  0.1000     Stationary
## 
## Conclusion for HEA : I(2) or higher - Further testing needed
## 
##  ------------------------------------- 
## Testing for: UNEMP 
## -------------------------------------
##              Test Statistic P_Value         Result
## 1       ADF Level   -2.7132  0.2987 Non-Stationary
## 2  ADF First Diff   -1.5153  0.7584 Non-Stationary
## 3        PP Level   -9.8984  0.4889 Non-Stationary
## 4   PP First Diff  -14.3069  0.1952 Non-Stationary
## 5      KPSS Level    0.3606  0.0941     Stationary
## 6 KPSS First Diff    0.1330  0.1000     Stationary
## 
## Conclusion for UNEMP : I(2) or higher - Further testing needed

OPTIMAL LAG SELECTION

cat("\n", "========== OPTIMAL LAG SELECTION ==========", "\n")
## 
##  ========== OPTIMAL LAG SELECTION ==========
# Create a dataframe with all variables
ardl_data <- data.frame(
  ECNDEV = as.numeric(ECNDEV),
  INF = as.numeric(INF),
  K = as.numeric(K),
  L = as.numeric(L),
  EDU = as.numeric(EDU),
  HEA = as.numeric(HEA),
  UNEMP = as.numeric(UNEMP)
)
# Remove any rows with NA
ardl_data <- na.omit(ardl_data)
# Function to select optimal lags using ARDL package
max_lags <- 4  # Adjust based on your data frequency and sample size

# Try different lag combinations and select based on AIC
aic_values <- data.frame(matrix(NA, nrow = max_lags, ncol = max_lags))
bic_values <- data.frame(matrix(NA, nrow = max_lags, ncol = max_lags))

cat("\nSearching for optimal lags...\n")
## 
## Searching for optimal lags...
for(i in 1:max_lags) {
  for(j in 1:max_lags) {
    tryCatch({
      # Estimate ARDL model with different lags
      ardl_temp <- ardl(
        ECNDEV ~ INF + K + L + EDU + HEA + UNEMP, 
        data = ardl_data,
        order = c(i, j, j, j, j, j, j)  # Different lags for dependent and independent variables
      )
      aic_values[i, j] <- AIC(ardl_temp)
      bic_values[i, j] <- BIC(ardl_temp)
    }, error = function(e) {
      # Skip if model cannot be estimated
    })
  }
}
# Find minimum AIC and BIC
min_aic <- which(aic_values == min(aic_values, na.rm = TRUE), arr.ind = TRUE)
min_bic <- which(bic_values == min(bic_values, na.rm = TRUE), arr.ind = TRUE)

cat("\nOptimal lags based on AIC: ECNDEV lag =", min_aic[1], ", Independent vars lag =", min_aic[2], "\n")
## 
## Optimal lags based on AIC: ECNDEV lag = 1 , Independent vars lag = 2
cat("Optimal lags based on BIC: ECNDEV lag =", min_bic[1], ", Independent vars lag =", min_bic[2], "\n")
## Optimal lags based on BIC: ECNDEV lag = 1 , Independent vars lag = 2
# Choose lags (using AIC as default)
ardl_lags <- c(min_aic[1], rep(min_aic[2], 6))
names(ardl_lags) <- c("ECNDEV", "INF", "K", "EDU", "HEA", "UNEMP")
cat("\nSelected lags:\n")
## 
## Selected lags:
print(ardl_lags)
## ECNDEV    INF      K    EDU    HEA  UNEMP   <NA> 
##      1      2      2      2      2      2      2

ARDL MODEL ESTIMATION

cat("\n", "========== ARDL MODEL ESTIMATION ==========", "\n")
## 
##  ========== ARDL MODEL ESTIMATION ==========
# Estimate ARDL model with selected lags
ardl_model <- ardl(
  ECNDEV ~ INF + K + L + EDU + HEA + UNEMP, 
  data = ardl_data,
  order = ardl_lags
)

cat("\nARDL Model Summary:\n")
## 
## ARDL Model Summary:
summary(ardl_model)
## 
## Time series regression with "ts" data:
## Start = 3, End = 30
## 
## Call:
## dynlm::dynlm(formula = full_formula, data = data, start = start, 
##     end = end)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -0.0231366 -0.0041264  0.0007817  0.0048398  0.0103761 
## 
## Coefficients: (3 not defined because of singularities)
##                Estimate Std. Error t value Pr(>|t|)  
## (Intercept)   3.773e-01  1.832e-01   2.059   0.0640 .
## L(ECNDEV, 1)  4.627e-01  2.948e-01   1.570   0.1447  
## INF          -8.384e-05  8.025e-04  -0.104   0.9187  
## L(INF, 1)    -5.696e-05  4.212e-04  -0.135   0.8949  
## L(INF, 2)    -3.033e-04  2.837e-04  -1.069   0.3079  
## K             8.720e-08  1.379e-06   0.063   0.9507  
## L(K, 1)      -7.689e-07  1.514e-06  -0.508   0.6215  
## L(K, 2)       1.164e-06  2.021e-06   0.576   0.5764  
## L            -1.080e-02  1.146e-02  -0.942   0.3662  
## L(L, 1)       1.325e-02  1.764e-02   0.751   0.4685  
## L(L, 2)       1.384e-02  3.426e-02   0.404   0.6939  
## EDU          -5.290e-02  2.578e-02  -2.052   0.0647 .
## L(EDU, 1)     3.931e-02  4.303e-02   0.913   0.3806  
## L(EDU, 2)     7.762e-03  2.724e-02   0.285   0.7809  
## HEA           6.422e-03  8.675e-03   0.740   0.4747  
## L(HEA, 1)    -6.273e-04  8.920e-03  -0.070   0.9452  
## L(HEA, 2)     9.790e-03  8.764e-03   1.117   0.2878  
## UNEMP                NA         NA      NA       NA  
## L(UNEMP, 1)          NA         NA      NA       NA  
## L(UNEMP, 2)          NA         NA      NA       NA  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.01041 on 11 degrees of freedom
## Multiple R-squared:  0.9447, Adjusted R-squared:  0.8643 
## F-statistic: 11.75 on 16 and 11 DF,  p-value: 0.0001024

LONG-RUN AND SHORT-RUN RELATIONSHIPS

cat("\n\n", "========== LONG-RUN AND SHORT-RUN RELATIONSHIPS ==========", "\n")
## 
## 
##  ========== LONG-RUN AND SHORT-RUN RELATIONSHIPS ==========
# Get long-run coefficients
cat("\nLong-run coefficients:\n")
## 
## Long-run coefficients:
tryCatch({
  long_run <- multipliers(ardl_model, type = "lr")
  print(long_run)
}, error = function(e) {
  cat("Could not compute long-run multipliers:", e$message, "\n")
  
  # Alternative: Manual long-run coefficients
  cat("\nEstimating long-run coefficients from UECM...\n")
  coef_uecm <- coef(uecm_model)
  
  # Long-run coefficients = -(coefficient of lagged independent / coefficient of lagged dependent)
  lr_coefficients <- data.frame(
    Variable = c("INF", "K", "L", "EDU", "HEA", "UNEMP"),
    Coefficient = -c(
      coef_uecm["INF_lag1"] / coef_uecm["ECNDEV_lag1"],
      coef_uecm["K_lag1"] / coef_uecm["ECNDEV_lag1"],
      coef_uecm["L_lag1"] / coef_uecm["ECNDEV_lag1"],
      coef_uecm["EDU_lag1"] / coef_uecm["ECNDEV_lag1"],
      coef_uecm["HEA_lag1"] / coef_uecm["ECNDEV_lag1"],
      coef_uecm["UNEMP_lag1"] / coef_uecm["ECNDEV_lag1"]
    )
  )
  print(lr_coefficients)
})
##          Term      Estimate Std. Error t value Pr(>|t|)
## 1 (Intercept)  7.021894e-01         NA      NA       NA
## 2         INF -8.265266e-04         NA      NA       NA
## 3           K  8.969899e-07         NA      NA       NA
## 4           L  3.032229e-02         NA      NA       NA
## 5         EDU -1.084842e-02         NA      NA       NA
## 6         HEA  2.900716e-02         NA      NA       NA
## 7       UNEMP            NA         NA      NA       NA

DIAGNOSTIC TESTS

cat("\n", "========== DIAGNOSTIC TESTS ==========", "\n")
## 
##  ========== DIAGNOSTIC TESTS ==========
# Residual diagnostics
residuals <- residuals(ardl_model)

# Normality test
cat("\nJarque-Bera Normality Test:\n")
## 
## Jarque-Bera Normality Test:
jb_test <- jarque.bera.test(residuals)
print(jb_test)
## 
##  Jarque Bera Test
## 
## data:  residuals
## X-squared = 22.259, df = 2, p-value = 1.468e-05
# Autocorrelation test
cat("\nBreusch-Godfrey Serial Correlation Test:\n")
## 
## Breusch-Godfrey Serial Correlation Test:
bg_test <- bgtest(ardl_model, order = ardl_lags[1])
print(bg_test)
## 
##  Breusch-Godfrey test for serial correlation of order up to 1
## 
## data:  ardl_model
## LM test = 2.2826, df = 1, p-value = 0.1308
# Heteroskedasticity test
cat("\nBreusch-Pagan Heteroskedasticity Test:\n")
## 
## Breusch-Pagan Heteroskedasticity Test:
bp_test <- bptest(ardl_model)
print(bp_test)
## 
##  studentized Breusch-Pagan test
## 
## data:  ardl_model
## BP = 15.986, df = 16, p-value = 0.454

STABILITY TESTS

cat("\n", "========== CUSUM STABILITY TEST ==========", "\n")
## 
##  ========== CUSUM STABILITY TEST ==========
# Create stability plots
par(mfrow = c(1, 2))

# OLS-CUSUM test
tryCatch({
  cusum_test <- efp(ardl_model, type = "OLS-CUSUM")
  plot(cusum_test, main = "OLS-CUSUM Test", 
       ylim = c(-2, 2), col = "blue", lwd = 2)
  # Add critical bounds at 5% significance
  abline(h = 1.358, col = "red", lty = 2, lwd = 2)
  abline(h = -1.358, col = "red", lty = 2, lwd = 2)
  grid()
}, error = function(e) {
  cat("CUSUM test could not be performed:", e$message, "\n")
})
## CUSUM test could not be performed: object 'ECNDEV' not found
# Recursive residuals
tryCatch({
  rec_resid <- recresid(ardl_model)
  plot(rec_resid, type = "l", main = "Recursive Residuals",
       ylab = "Recursive Residuals", col = "darkgreen", lwd = 2)
  abline(h = 0, col = "red", lty = 2)
  grid()
}, error = function(e) {
  cat("Recursive residuals could not be computed:", e$message, "\n")
})

par(mfrow = c(1, 1))

PLOTS

cat("\n", "========== DIAGNOSTIC PLOTS ==========", "\n")
## 
##  ========== DIAGNOSTIC PLOTS ==========
# Set up plotting area
par(mfrow = c(2, 2))

# Plot actual vs fitted
plot(ardl_data$ECNDEV, type = "l", col = "blue", lwd = 2, 
     main = "Actual vs Fitted ECNDEV", 
     xlab = "Time", ylab = "ECNDEV")
lines(fitted(ardl_model), col = "red", lwd = 2, lty = 2)
legend("topright", legend = c("Actual", "Fitted"), 
       col = c("blue", "red"), lty = c(1, 2), cex = 0.8)

# Plot residuals
plot(residuals, type = "l", main = "Model Residuals", 
     xlab = "Time", ylab = "Residuals", col = "darkgreen", lwd = 2)
abline(h = 0, col = "red", lty = 2)
grid()

# ACF of residuals
acf(residuals, main = "ACF of Residuals", lag.max = 10, col = "blue", lwd = 2)

# QQ plot
qqnorm(residuals, main = "Q-Q Plot of Residuals", 
       col = "blue", pch = 19, cex = 0.7)
qqline(residuals, col = "red", lwd = 2)

par(mfrow = c(1, 1))

FINAL SUMMARY

cat("\n", "========== FINAL SUMMARY ==========", "\n")
## 
##  ========== FINAL SUMMARY ==========
cat("\nARDL Model Specification:")
## 
## ARDL Model Specification:
cat("\n- Dependent Variable: ECNDEV")
## 
## - Dependent Variable: ECNDEV
cat("\n- Independent Variables: INF, K, L, EDU, HEA, UNEMP")
## 
## - Independent Variables: INF, K, L, EDU, HEA, UNEMP
cat("\n- Selected Lags: ECNDEV(", ardl_lags[1], "), Others(", ardl_lags[2], ")", sep = "")
## 
## - Selected Lags: ECNDEV(1), Others(2)
cat("\n\nModel Fit:")
## 
## 
## Model Fit:
cat("\n- R-squared:", round(summary(ardl_model)$r.squared, 4))
## 
## - R-squared: 0.9447
cat("\n- Adjusted R-squared:", round(summary(ardl_model)$adj.r.squared, 4))
## 
## - Adjusted R-squared: 0.8643
if(exists("bounds_test")) {
  cat("\n\nCointegration Test:")
  cat("\n- F-statistic:", round(f_stat, 4))
  cat("\n- Critical Values (5%): I(0) =", round(i0_bound_5, 4), 
      ", I(1) =", round(i1_bound_5, 4))
  
  if(f_stat > i1_bound_5) {
    cat("\n- ✓ CONCLUSION: Cointegration exists - Long-run relationship confirmed")
  } else if(f_stat < i0_bound_5) {
    cat("\n- ✗ CONCLUSION: No cointegration detected")
  } else {
    cat("\n- ? CONCLUSION: Inconclusive - Further testing needed")
  }
}

cat("\n\nDiagnostic Tests Summary:")
## 
## 
## Diagnostic Tests Summary:
cat("\n- Normality (Jarque-Bera p-value):", round(jb_test$p.value, 4))
## 
## - Normality (Jarque-Bera p-value): 0
cat("\n- Autocorrelation (BG test p-value):", round(bg_test$p.value, 4))
## 
## - Autocorrelation (BG test p-value): 0.1308
cat("\n- Heteroskedasticity (BP test p-value):", round(bp_test$p.value, 4))
## 
## - Heteroskedasticity (BP test p-value): 0.454
cat("\n\n========================================\n")
## 
## 
## ========================================

Bounds test working

model <- ardlBound(data = data,
                   formula = ECNDEV ~ INF + L+ EDU + HEA,
                   max.p = 1,
                   max.q = 1)
##   
## Orders being calculated with max.p = 1 and max.q = 1 ...
## 
## Autoregressive order: 2 and p-orders: 1 2 1 2 
## ------------------------------------------------------ 
## 
##  Breusch-Godfrey Test for the autocorrelation in residuals:
## 
##  Breusch-Godfrey test for serial correlation of order up to 1
## 
## data:  modelFull$model
## LM test = 0.52891, df1 = 1, df2 = 14, p-value = 0.4791
## 
## ------------------------------------------------------ 
## 
##  Ljung-Box Test for the autocorrelation in residuals:
## 
##  Box-Ljung test
## 
## data:  res
## X-squared = 0.41898, df = 1, p-value = 0.5174
## 
## ------------------------------------------------------ 
## 
##  Breusch-Pagan Test for the homoskedasticity of residuals:
## 
##  studentized Breusch-Pagan test
## 
## data:  modelFull$model
## BP = 12.558, df = 12, p-value = 0.402
## 
## ------------------------------------------------------ 
## 
##  Shapiro-Wilk test of normality of residuals:
## 
##  Shapiro-Wilk normality test
## 
## data:  modelFull$model$residual
## W = 0.80802, p-value = 0.0001483
## 
## The p-value of Shapiro-Wilk test normality of residuals:  0.00014829 < 0.05!
## ------------------------------------------------------ 
## 
##  PESARAN, SHIN AND SMITH (2001) COINTEGRATION TEST 
## 
##  Observations: 29 
##  Number of Regressors (k): 4 
##  Case: 3 
## 
##  ------------------------------------------------------ 
##  -                       F-test                       - 
##  ------------------------------------------------------ 
##                  <------- I(0) ------------ I(1) -----> 
##  10% critical value       2.752            3.994 
##  5% critical value        3.354            4.774 
##  1% critical value        4.768            6.67 
##  
## 
##  F-statistic = 1.12891184038808 
##   
##  ------------------------------------------------------ 
##  
##  
## ------------------------------------------------------ 
## 
##  Ramsey's RESET Test for model specification:
## 
##  RESET test
## 
## data:  modelECM$model
## RESET = 173.27, df1 = 2, df2 = 17, p-value = 4.945e-12
## 
## the p-value of RESET test:  4.945172e-12 < 0.05!
## ------------------------------------------------------
## ------------------------------------------------------ 
## Error Correction Model Output: 
## 
## Time series regression with "ts" data:
## Start = 2, End = 29
## 
## Call:
## dynlm(formula = as.formula(model.text), data = data)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -0.0282540 -0.0035603  0.0003741  0.0055888  0.0088744 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept)  0.2482325  0.0873063   2.843  0.01039 * 
## ec.1        -0.3636814  0.1360113  -2.674  0.01501 * 
## dINF.t       0.0001554  0.0001970   0.789  0.44000   
## dL.t        -0.0106164  0.0057515  -1.846  0.08055 . 
## dL.1        -0.0140458  0.0075009  -1.873  0.07660 . 
## dEDU.t      -0.0484982  0.0141109  -3.437  0.00276 **
## dHEA.t       0.0065085  0.0059423   1.095  0.28708   
## dHEA.1      -0.0119362  0.0056936  -2.096  0.04966 * 
## dECNDEV.1   -0.1714593  0.1928196  -0.889  0.38500   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.008586 on 19 degrees of freedom
## Multiple R-squared:  0.4667, Adjusted R-squared:  0.2422 
## F-statistic: 2.079 on 8 and 19 DF,  p-value: 0.091
## 
## ------------------------------------------------------ 
## Long-run coefficients: 
##      ECNDEV.1         INF.1           L.1         EDU.1         HEA.1 
## -0.3636813613 -0.0001208959  0.0118454398 -0.0047702588  0.0160422061 
## 
summary(model)
##            Length Class      Mode   
## model       2     -none-     list   
## F.stat      1     -none-     numeric
## p           5     data.frame list   
## k           1     -none-     numeric
## bg          7     bgtest     list   
## lb          5     htest      list   
## bp          5     htest      list   
## sp          4     htest      list   
## ECM         4     -none-     list   
## ARDL.model 15     dynlm      list

References

Pesaran, M. H., Shin, Y., & Smith, R. J. (2001). Bounds testing approaches to the analysis of level relationships. Journal of Applied Econometrics, 16(3), 289–326.https://doi.org/10.1002/jae.616

Pesaran, M. H., & Smith, R. (1995). Estimating long-run relationships from dynamic heterogeneous panels. Journal of Econometrics, 68(1), 79–113.https://doi.org/10.1016/0304-4076(94)01644-F