# 1. 載入套件
library(readxl)
## Warning: package 'readxl' was built under R version 4.5.2
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.5.2
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.2
library(sandwich)

# 2. 讀取 Excel
raw <- read_excel(
  "~/Desktop/wh/Asean1029.xlsx",
  .name_repair = "unique"
)
## New names:
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...13`
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...14`
# 3. 清除欄位名稱前後空格
names(raw) <- trimws(names(raw))

# 4. 整理變數
d <- raw %>%
  transmute(
    Country = as.character(Country),
    Year = as.integer(Year),

    UNGA = as.numeric(`UNGA Position Index`),
    ISEAS = as.numeric(`ISEAS Elite preference`),

    Democracy = as.numeric(`Democracy EIU`),
    SCS = as.numeric(SCS),
    Post2022 = as.integer(Year >= 2022),

    PolStab = as.numeric(`Political Stability`),
    FSI = as.numeric(`FSI  (100 - raw FSI)`),

    USAlly = as.numeric(
      `US Formal Defense Ally (1/0)`
    ),

    TradeChina = as.numeric(raw[[14]])
  )

# 5. 建立 UNGA 回歸資料
unga_data <- d %>%
  drop_na(
    Country, UNGA, Democracy, SCS,
    Post2022, TradeChina, USAlly,
    PolStab, FSI
  )

# 6. 建立 ISEAS 回歸資料
iseas_data <- d %>%
  drop_na(
    Country, ISEAS, Democracy, SCS,
    Post2022, TradeChina, USAlly,
    PolStab, FSI
  )
library(readxl)
library(dplyr)
library(tidyr)

# 1. 讀取 Excel
raw <- read_excel(
  "~/Desktop/wh/Asean1029.xlsx",
  .name_repair = "unique"
)
## New names:
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...13`
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...14`
# 2. 清除欄位名稱前後空格
names(raw) <- trimws(names(raw))

# 3. 整理研究變數
d <- raw %>%
  transmute(
    Country = as.character(Country),
    Year = as.integer(Year),

    # 依變數
    UNGA = as.numeric(`UNGA Position Index`),
    ISEAS = as.numeric(`ISEAS Elite preference`),

    # 核心自變數
    Democracy = as.numeric(`Democracy EIU`),
    SCS = as.numeric(SCS),
    Post2022 = as.integer(Year >= 2022),

    # 控制變數
    TradeChina = as.numeric(raw[[14]]),
    USAlly = as.numeric(`US Formal Defense Ally (1/0)`),
    PolStab = as.numeric(`Political Stability`),
    FSI = as.numeric(`FSI  (100 - raw FSI)`)
  )

# 4. 確認資料
head(d)
## # A tibble: 6 × 11
##   Country   Year  UNGA ISEAS Democracy   SCS Post2022 TradeChina USAlly PolStab
##   <chr>    <int> <dbl> <dbl>     <dbl> <dbl>    <int>      <dbl>  <dbl>   <dbl>
## 1 Cambodia  2010 1.01     NA      4.87     0        0     0.0906      0    58.3
## 2 Cambodia  2011 1.11     NA      4.87     0        0     0.118       0    59.4
## 3 Cambodia  2012 0.844    NA      4.96     0        0     0.135       0    58.6
## 4 Cambodia  2013 1.09     NA      4.6      0        0     0.165       0    58.6
## 5 Cambodia  2014 0.949    NA      4.78     0        0     0.334       0    60.2
## 6 Cambodia  2015 1.50     NA      4.27     0        0     0.346       0    62.1
## # ℹ 1 more variable: FSI <dbl>
names(d)
##  [1] "Country"    "Year"       "UNGA"       "ISEAS"      "Democracy" 
##  [6] "SCS"        "Post2022"   "TradeChina" "USAlly"     "PolStab"   
## [11] "FSI"
nrow(d)
## [1] 128
# =====================================
# Step 2: Check Available Observations
# =====================================

# 1. UNGA:完整模型可用資料
unga_data <- d %>%
  drop_na(
    Country, UNGA, Democracy, SCS, Post2022,
    TradeChina, USAlly, PolStab, FSI
  )

# 2. ISEAS:完整模型可用資料
iseas_data <- d %>%
  drop_na(
    Country, ISEAS, Democracy, SCS, Post2022,
    TradeChina, USAlly, PolStab, FSI
  )

# 3. 檢查樣本數與年份
data.frame(
  Model = c("UNGA", "ISEAS"),
  N = c(nrow(unga_data), nrow(iseas_data)),
  StartYear = c(
    min(unga_data$Year),
    min(iseas_data$Year)
  ),
  EndYear = c(
    max(unga_data$Year),
    max(iseas_data$Year)
  ),
  Countries = c(
    n_distinct(unga_data$Country),
    n_distinct(iseas_data$Country)
  )
)
##   Model   N StartYear EndYear Countries
## 1  UNGA 120      2010    2024         8
## 2 ISEAS  48      2019    2024         8
# =====================================
# Step 3: OLS Regression Models
# =====================================

# UNGA Position Index

# M1:核心自變數
m1 <- lm(
  UNGA ~ Democracy + SCS + Post2022,
  data = unga_data
)

# M2:加入主要控制變數
m2 <- lm(
  UNGA ~ Democracy + SCS + Post2022 +
    TradeChina + USAlly,
  data = unga_data
)

# M3:完整模型
m3 <- lm(
  UNGA ~ Democracy + SCS + Post2022 +
    TradeChina + USAlly + PolStab + FSI,
  data = unga_data
)


# ISEAS Elite Preference

# M4:核心自變數
m4 <- lm(
  ISEAS ~ Democracy + SCS + Post2022,
  data = iseas_data
)

# M5:加入主要控制變數
m5 <- lm(
  ISEAS ~ Democracy + SCS + Post2022 +
    TradeChina + USAlly,
  data = iseas_data
)

# M6:完整模型
m6 <- lm(
  ISEAS ~ Democracy + SCS + Post2022 +
    TradeChina + USAlly + PolStab + FSI,
  data = iseas_data
)


# 查看六組模型結果
summary(m1)
## 
## Call:
## lm(formula = UNGA ~ Democracy + SCS + Post2022, data = unga_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.38597 -0.12766 -0.00277  0.10456  0.50185 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.39894    0.05595  25.005  < 2e-16 ***
## Democracy   -0.05487    0.01020  -5.380 3.92e-07 ***
## SCS          0.02458    0.03748   0.656    0.513    
## Post2022    -0.40730    0.04488  -9.076 3.47e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1966 on 116 degrees of freedom
## Multiple R-squared:  0.4862, Adjusted R-squared:  0.4729 
## F-statistic: 36.59 on 3 and 116 DF,  p-value: < 2.2e-16
summary(m2)
## 
## Call:
## lm(formula = UNGA ~ Democracy + SCS + Post2022 + TradeChina + 
##     USAlly, data = unga_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.42404 -0.11632 -0.01333  0.14055  0.42105 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.39640    0.07481  18.665  < 2e-16 ***
## Democracy   -0.04213    0.01076  -3.917 0.000153 ***
## SCS          0.04357    0.03544   1.230 0.221409    
## Post2022    -0.39777    0.04363  -9.117 3.15e-15 ***
## TradeChina  -0.12057    0.17509  -0.689 0.492462    
## USAlly      -0.19015    0.04384  -4.338 3.12e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1834 on 114 degrees of freedom
## Multiple R-squared:  0.5606, Adjusted R-squared:  0.5413 
## F-statistic: 29.09 on 5 and 114 DF,  p-value: < 2.2e-16
summary(m3)
## 
## Call:
## lm(formula = UNGA ~ Democracy + SCS + Post2022 + TradeChina + 
##     USAlly + PolStab + FSI, data = unga_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.39378 -0.10970 -0.00452  0.12027  0.43113 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.540379   0.236814   6.505 2.26e-09 ***
## Democracy   -0.024204   0.015667  -1.545    0.125    
## SCS          0.024443   0.034543   0.708    0.481    
## Post2022    -0.384650   0.042393  -9.073 4.53e-15 ***
## TradeChina   0.175948   0.191510   0.919    0.360    
## USAlly      -0.274630   0.058201  -4.719 6.91e-06 ***
## PolStab     -0.003023   0.003644  -0.829    0.409    
## FSI         -0.002608   0.002399  -1.087    0.279    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1764 on 112 degrees of freedom
## Multiple R-squared:  0.6009, Adjusted R-squared:  0.576 
## F-statistic: 24.09 on 7 and 112 DF,  p-value: < 2.2e-16
summary(m4)
## 
## Call:
## lm(formula = ISEAS ~ Democracy + SCS + Post2022, data = iseas_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -33.389 -15.838  -0.067  11.716  34.599 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   56.019      7.954   7.043 9.89e-09 ***
## Democracy     -5.589      1.391  -4.018 0.000226 ***
## SCS           23.554      5.699   4.133 0.000158 ***
## Post2022      -6.570      5.417  -1.213 0.231633    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.76 on 44 degrees of freedom
## Multiple R-squared:  0.4002, Adjusted R-squared:  0.3593 
## F-statistic: 9.785 on 3 and 44 DF,  p-value: 4.594e-05
summary(m5)
## 
## Call:
## lm(formula = ISEAS ~ Democracy + SCS + Post2022 + TradeChina + 
##     USAlly, data = iseas_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -28.508 -13.370  -0.626  12.638  41.630 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   76.329     14.822   5.150 6.54e-06 ***
## Democracy     -7.950      1.823  -4.361 8.22e-05 ***
## SCS           25.063      5.773   4.341 8.75e-05 ***
## Post2022      -5.288      5.366  -0.985    0.330    
## TradeChina   -45.105     30.771  -1.466    0.150    
## USAlly         5.802      7.113   0.816    0.419    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.34 on 42 degrees of freedom
## Multiple R-squared:  0.453,  Adjusted R-squared:  0.3879 
## F-statistic: 6.958 on 5 and 42 DF,  p-value: 8.196e-05
summary(m6)
## 
## Call:
## lm(formula = ISEAS ~ Democracy + SCS + Post2022 + TradeChina + 
##     USAlly + PolStab + FSI, data = iseas_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -27.905 -12.645  -3.152   8.675  34.670 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  86.8143    37.4752   2.317 0.025732 *  
## Democracy   -10.4312     2.8067  -3.716 0.000618 ***
## SCS          26.5384     5.8962   4.501 5.72e-05 ***
## Post2022     -5.8967     5.3668  -1.099 0.278458    
## TradeChina  -60.6256    32.4169  -1.870 0.068789 .  
## USAlly       10.9506     8.4203   1.301 0.200872    
## PolStab      -0.1522     0.5620  -0.271 0.787881    
## FSI           0.4040     0.3887   1.039 0.304945    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.29 on 40 degrees of freedom
## Multiple R-squared:  0.482,  Adjusted R-squared:  0.3914 
## F-statistic: 5.318 on 7 and 40 DF,  p-value: 0.0002351
# =====================================
# Step 4-1: Define get_coef Function
# =====================================

library(broom)
library(lmtest)
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.5.2
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(sandwich)
library(dplyr)

get_coef <- function(model, data, label) {

  # 計算國家叢集標準誤
  V <- sandwich::vcovCL(
    model,
    cluster = data$Country,
    type = "HC1"
  )

  # 提取迴歸係數及標準誤
  result <- broom::tidy(
    lmtest::coeftest(model, vcov. = V)
  )

  # 國家數量
  G <- dplyr::n_distinct(data$Country)

  # 95% 信賴區間
  critical <- qt(0.975, df = G - 1)

  result %>%
    dplyr::mutate(
      conf.low = estimate - critical * std.error,
      conf.high = estimate + critical * std.error,
      Model = label
    )
}
# =====================================
# Step 4-2: Prepare Coefficient Data
# =====================================

coef_data <- dplyr::bind_rows(
  get_coef(m3, unga_data, "UNGA Position Index"),
  get_coef(m6, iseas_data, "ISEAS Elite Preference")
) %>%
  dplyr::filter(term != "(Intercept)") %>%
  dplyr::mutate(
    Variable = dplyr::recode(
      term,
      "Democracy" = "Democracy",
      "SCS" = "SCS Claimant",
      "Post2022" = "Post-2022",
      "TradeChina" = "Trade with China",
      "USAlly" = "U.S. Defense Ally",
      "PolStab" = "Political Stability",
      "FSI" = "State Capacity"
    ),

    Variable = factor(
      Variable,
      levels = rev(c(
        "Democracy",
        "SCS Claimant",
        "Post-2022",
        "Trade with China",
        "U.S. Defense Ally",
        "Political Stability",
        "State Capacity"
      ))
    )
  )

# 確認整理成功
print(coef_data)
## # A tibble: 14 × 9
##    term  estimate std.error statistic  p.value conf.low conf.high Model Variable
##    <chr>    <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl> <chr> <fct>   
##  1 Demo… -2.42e-2   0.0111     -2.18  3.13e- 2 -5.05e-2   0.00205 UNGA… Democra…
##  2 SCS    2.44e-2   0.0249      0.983 3.28e- 1 -3.44e-2   0.0833  UNGA… SCS Cla…
##  3 Post… -3.85e-1   0.0433     -8.88  1.24e-14 -4.87e-1  -0.282   UNGA… Post-20…
##  4 Trad…  1.76e-1   0.137       1.28  2.02e- 1 -1.48e-1   0.500   UNGA… Trade w…
##  5 USAl… -2.75e-1   0.0755     -3.64  4.18e- 4 -4.53e-1  -0.0961  UNGA… U.S. De…
##  6 PolS… -3.02e-3   0.00461    -0.655 5.14e- 1 -1.39e-2   0.00788 UNGA… Politic…
##  7 FSI   -2.61e-3   0.00292    -0.894 3.73e- 1 -9.50e-3   0.00429 UNGA… State C…
##  8 Demo… -1.04e+1   3.11       -3.36  1.74e- 3 -1.78e+1  -3.08    ISEA… Democra…
##  9 SCS    2.65e+1   7.74        3.43  1.42e- 3  8.24e+0  44.8     ISEA… SCS Cla…
## 10 Post… -5.90e+0   4.95       -1.19  2.41e- 1 -1.76e+1   5.81    ISEA… Post-20…
## 11 Trad… -6.06e+1  37.6        -1.61  1.14e- 1 -1.49e+2  28.2     ISEA… Trade w…
## 12 USAl…  1.10e+1  11.2         0.982 3.32e- 1 -1.54e+1  37.3     ISEA… U.S. De…
## 13 PolS… -1.52e-1   0.453      -0.336 7.39e- 1 -1.22e+0   0.919   ISEA… Politic…
## 14 FSI    4.04e-1   0.383       1.05  2.98e- 1 -5.02e-1   1.31    ISEA… State C…
# =====================================
# Step 5: Grayscale Coefficient Plot
# =====================================

library(ggplot2)

p_coef <- ggplot(
  coef_data,
  aes(x = estimate, y = Variable)
) +

  # 係數為零的參考線
  geom_vline(
    xintercept = 0,
    linetype = "dashed",
    color = "gray65",
    linewidth = 0.6
  ) +

  # 95% 信賴區間
  geom_errorbar(
    aes(xmin = conf.low, xmax = conf.high),
    orientation = "y",
    width = 0.15,
    linewidth = 0.8,
    color = "gray35"
  ) +

  # 迴歸係數
  geom_point(
    size = 3.2,
    shape = 21,
    fill = "black",
    color = "white",
    stroke = 0.5
  ) +

  # 分成 UNGA 和 ISEAS 兩個面板
  facet_wrap(
    ~ Model,
    scales = "free_x",
    nrow = 1
  ) +

  labs(
    title = "Determinants of ASEAN Strategic Positioning",
    subtitle = "OLS Coefficients with 95% Confidence Intervals",
    x = "Coefficient Estimate",
    y = NULL,
    caption = "Country-clustered standard errors (8 countries)."
  ) +

  theme_classic(base_size = 14) +

  theme(
    plot.title = element_text(
      face = "bold",
      size = 18
    ),
    plot.subtitle = element_text(
      color = "gray40",
      size = 12
    ),
    strip.text = element_text(
      face = "bold",
      size = 12
    ),
    strip.background = element_rect(
      fill = "gray92",
      color = NA
    ),
    panel.spacing = grid::unit(1.5, "lines"),
    axis.text.y = element_text(
      size = 11,
      color = "gray20"
    ),
    plot.caption = element_text(
      size = 9,
      color = "gray45"
    ),
    plot.margin = margin(18, 20, 15, 15)
  )

# 顯示圖片
print(p_coef)

# =====================================
# Step 7: Interaction Regression Models
# =====================================

# M7:UNGA × Democracy × Post2022
m7 <- lm(
  UNGA ~ Democracy * Post2022 +
    SCS + TradeChina + USAlly +
    PolStab + FSI,
  data = unga_data
)

# M8:UNGA × Democracy × SCS
m8 <- lm(
  UNGA ~ Democracy * SCS +
    Post2022 + TradeChina + USAlly +
    PolStab + FSI,
  data = unga_data
)

# M9:ISEAS × Democracy × Post2022
m9 <- lm(
  ISEAS ~ Democracy * Post2022 +
    SCS + TradeChina + USAlly +
    PolStab + FSI,
  data = iseas_data
)

# M10:ISEAS × Democracy × SCS
m10 <- lm(
  ISEAS ~ Democracy * SCS +
    Post2022 + TradeChina + USAlly +
    PolStab + FSI,
  data = iseas_data
)

# 查看四組迴歸結果
summary(m7)
## 
## Call:
## lm(formula = UNGA ~ Democracy * Post2022 + SCS + TradeChina + 
##     USAlly + PolStab + FSI, data = unga_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.39476 -0.10521 -0.00414  0.13043  0.41947 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         1.571794   0.236552   6.645 1.18e-09 ***
## Democracy          -0.030403   0.016144  -1.883   0.0623 .  
## Post2022           -0.545334   0.116978  -4.662 8.78e-06 ***
## SCS                 0.022047   0.034402   0.641   0.5229    
## TradeChina          0.246229   0.196405   1.254   0.2126    
## USAlly             -0.274202   0.057901  -4.736 6.49e-06 ***
## PolStab            -0.003155   0.003626  -0.870   0.3862    
## FSI                -0.002736   0.002388  -1.146   0.2543    
## Democracy:Post2022  0.030942   0.021011   1.473   0.1437    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1754 on 111 degrees of freedom
## Multiple R-squared:  0.6086, Adjusted R-squared:  0.5804 
## F-statistic: 21.57 on 8 and 111 DF,  p-value: < 2.2e-16
summary(m8)
## 
## Call:
## lm(formula = UNGA ~ Democracy * SCS + Post2022 + TradeChina + 
##     USAlly + PolStab + FSI, data = unga_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.39932 -0.11749 -0.00476  0.12367  0.43175 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    1.470545   0.315464   4.662 8.79e-06 ***
## Democracy     -0.018435   0.023254  -0.793    0.430    
## SCS            0.069444   0.138036   0.503    0.616    
## Post2022      -0.381647   0.043485  -8.776 2.31e-14 ***
## TradeChina     0.170956   0.192843   0.887    0.377    
## USAlly        -0.265885   0.063941  -4.158 6.34e-05 ***
## PolStab       -0.002086   0.004595  -0.454    0.651    
## FSI           -0.003267   0.003103  -1.053    0.295    
## Democracy:SCS -0.008564   0.025427  -0.337    0.737    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1771 on 111 degrees of freedom
## Multiple R-squared:  0.6013, Adjusted R-squared:  0.5726 
## F-statistic: 20.93 on 8 and 111 DF,  p-value: < 2.2e-16
summary(m9)
## 
## Call:
## lm(formula = ISEAS ~ Democracy * Post2022 + SCS + TradeChina + 
##     USAlly + PolStab + FSI, data = iseas_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -29.105 -13.755  -1.354   9.885  35.675 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         90.2152    38.0385   2.372 0.022739 *  
## Democracy          -11.2813     3.0797  -3.663 0.000739 ***
## Post2022           -15.5550    14.9408  -1.041 0.304237    
## SCS                 26.4649     5.9358   4.458  6.8e-05 ***
## TradeChina         -56.9523    33.0567  -1.723 0.092834 .  
## USAlly              11.1410     8.4799   1.314 0.196586    
## PolStab             -0.1475     0.5657  -0.261 0.795634    
## FSI                  0.3965     0.3914   1.013 0.317379    
## Democracy:Post2022   1.8875     2.7223   0.693 0.492202    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.41 on 39 degrees of freedom
## Multiple R-squared:  0.4883, Adjusted R-squared:  0.3834 
## F-statistic: 4.653 on 8 and 39 DF,  p-value: 0.0004757
summary(m10)
## 
## Call:
## lm(formula = ISEAS ~ Democracy * SCS + Post2022 + TradeChina + 
##     USAlly + PolStab + FSI, data = iseas_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -31.125 -12.476  -1.477  10.960  35.417 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)  
## (Intercept)    205.855     91.092   2.260   0.0295 *
## Democracy      -20.873      7.809  -2.673   0.0109 *
## SCS            -30.835     40.539  -0.761   0.4515  
## Post2022        -6.974      5.351  -1.303   0.2001  
## TradeChina     -57.567     32.073  -1.795   0.0804 .
## USAlly          10.567      8.317   1.271   0.2114  
## PolStab         -1.906      1.346  -1.416   0.1647  
## FSI              1.746      1.014   1.722   0.0930 .
## Democracy:SCS   10.686      7.472   1.430   0.1607  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.05 on 39 degrees of freedom
## Multiple R-squared:  0.5078, Adjusted R-squared:  0.4069 
## F-statistic:  5.03 on 8 and 39 DF,  p-value: 0.0002478
# =====================================
# Interaction Prediction Data
# =====================================

library(dplyr)
library(sandwich)

make_prediction <- function(model, data, groupvar) {

  # 建立民主指數範圍
  pred <- expand.grid(
    Democracy = seq(
      min(data$Democracy, na.rm = TRUE),
      max(data$Democracy, na.rm = TRUE),
      length.out = 100
    ),
    Group = c(0, 1)
  )

  # 其他變數固定在樣本平均值
  pred$Post2022 <- mean(data$Post2022, na.rm = TRUE)
  pred$SCS <- mean(data$SCS, na.rm = TRUE)
  pred$TradeChina <- mean(data$TradeChina, na.rm = TRUE)
  pred$USAlly <- mean(data$USAlly, na.rm = TRUE)
  pred$PolStab <- mean(data$PolStab, na.rm = TRUE)
  pred$FSI <- mean(data$FSI, na.rm = TRUE)

  # 設定比較組別
  pred[[groupvar]] <- pred$Group

  # 國家叢集共變異數矩陣
  V <- sandwich::vcovCL(
    model,
    cluster = data$Country,
    type = "HC1"
  )

  # 計算預測值與標準誤
  X <- model.matrix(
    delete.response(terms(model)),
    data = pred
  )

  pred$fit <- as.vector(X %*% coef(model))

  pred$se <- sqrt(
    pmax(0, rowSums((X %*% V) * X))
  )

  # 95% 信賴區間
  G <- dplyr::n_distinct(data$Country)
  critical <- qt(0.975, df = G - 1)

  pred$lower <- pred$fit - critical * pred$se
  pred$upper <- pred$fit + critical * pred$se

  # 組別名稱
  if (groupvar == "Post2022") {
    pred$Category <- factor(
      pred$Group,
      levels = c(0, 1),
      labels = c("Pre-2022", "Post-2022")
    )
  } else {
    pred$Category <- factor(
      pred$Group,
      levels = c(0, 1),
      labels = c("Non-Claimant", "SCS Claimant")
    )
  }

  return(pred)
}


# =====================================
# 建立四組預測資料
# =====================================

pred1 <- make_prediction(m7, unga_data, "Post2022")
pred2 <- make_prediction(m8, unga_data, "SCS")
pred3 <- make_prediction(m9, iseas_data, "Post2022")
pred4 <- make_prediction(m10, iseas_data, "SCS")

# 確認成功
names(pred1)
##  [1] "Democracy"  "Group"      "Post2022"   "SCS"        "TradeChina"
##  [6] "USAlly"     "PolStab"    "FSI"        "fit"        "se"        
## [11] "lower"      "upper"      "Category"
head(pred1)
##   Democracy Group Post2022   SCS TradeChina USAlly  PolStab     FSI      fit
## 1  1.710000     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.227073
## 2  1.766465     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.225356
## 3  1.822929     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.223640
## 4  1.879394     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.221923
## 5  1.935859     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.220206
## 6  1.992323     0        0 0.375  0.2009302   0.25 63.11227 30.2703 1.218490
##           se    lower    upper Category
## 1 0.05025476 1.108239 1.345907 Pre-2022
## 2 0.04940771 1.108526 1.342187 Pre-2022
## 3 0.04856194 1.108809 1.338471 Pre-2022
## 4 0.04771751 1.109089 1.334757 Pre-2022
## 5 0.04687450 1.109366 1.331047 Pre-2022
## 6 0.04603298 1.109639 1.327340 Pre-2022
# =====================================
# Grayscale Interaction Plots
# =====================================

library(ggplot2)
library(dplyr)

# 1. 灰階繪圖函數
plot_interaction <- function(pred, title, subtitle, ylabel) {

  # 自動統一信賴區間欄位
  if (all(c("conf.low", "conf.high") %in% names(pred))) {
    pred$lower <- pred$conf.low
    pred$upper <- pred$conf.high
  } else if (all(c("low", "high") %in% names(pred))) {
    pred$lower <- pred$low
    pred$upper <- pred$high
  }

  # 自動建立組別標籤
  if (!"Category" %in% names(pred)) {
    if ("Period" %in% names(pred)) {
      pred$Category <- pred$Period
    } else if ("SCS_Group" %in% names(pred)) {
      pred$Category <- pred$SCS_Group
    } else if ("Post2022" %in% names(pred) &&
               length(unique(pred$Post2022)) == 2) {
      pred$Category <- ifelse(
        pred$Post2022 == 1, "Post-2022", "Pre-2022"
      )
    } else if ("SCS" %in% names(pred) &&
               length(unique(pred$SCS)) == 2) {
      pred$Category <- ifelse(
        pred$SCS == 1, "SCS Claimant", "Non-Claimant"
      )
    }
  }

  # 確認必要欄位存在
  required <- c(
    "Democracy", "fit", "lower", "upper", "Category"
  )

  missing <- setdiff(required, names(pred))

  if (length(missing) > 0) {
    stop(
      "Missing columns: ",
      paste(missing, collapse = ", ")
    )
  }

  pred$Category <- factor(pred$Category)
  groups <- levels(pred$Category)

  # 繪圖
  ggplot(
    pred,
    aes(x = Democracy, y = fit, group = Category)
  ) +
    geom_ribbon(
      aes(
        ymin = lower,
        ymax = upper,
        fill = Category
      ),
      alpha = 0.22,
      colour = NA
    ) +
    geom_line(
      aes(
        linetype = Category,
        colour = Category
      ),
      linewidth = 1.2
    ) +
    scale_colour_manual(
      values = setNames(
        c("#666666", "#111111"),
        groups
      )
    ) +
    scale_fill_manual(
      values = setNames(
        c("#BBBBBB", "#777777"),
        groups
      )
    ) +
    scale_linetype_manual(
      values = setNames(
        c("dashed", "solid"),
        groups
      )
    ) +
    labs(
      title = title,
      subtitle = subtitle,
      x = "Democracy Index (EIU)",
      y = ylabel,
      colour = NULL,
      fill = NULL,
      linetype = NULL,
      caption = "OLS predictions with 95% confidence intervals."
    ) +
    theme_classic(base_size = 14) +
    theme(
      plot.title = element_text(
        face = "bold",
        size = 19
      ),
      plot.subtitle = element_text(
        colour = "gray40",
        size = 12
      ),
      axis.title = element_text(
        face = "bold",
        size = 13
      ),
      axis.text = element_text(
        colour = "gray30",
        size = 11
      ),
      legend.position = "bottom",
      legend.text = element_text(size = 12),
      legend.key.width = grid::unit(2.5, "cm"),
      plot.caption = element_text(
        colour = "gray50",
        size = 9
      )
    ) +
    guides(
      fill = "none",
      linetype = "none"
    )
}


# =====================================
# 2. 建立四張圖
# =====================================

p1 <- plot_interaction(
  pred1,
  "Democracy × Post-2022",
  "Changes in Diplomatic Positioning",
  "Predicted UNGA Position Index"
)

p2 <- plot_interaction(
  pred2,
  "Democracy × SCS Claimant",
  "Differences by South China Sea Exposure",
  "Predicted UNGA Position Index"
)

p3 <- plot_interaction(
  pred3,
  "Democracy × Post-2022",
  "Changes in Elite Strategic Preferences",
  "Predicted Elite Preference Distance"
)

p4 <- plot_interaction(
  pred4,
  "Democracy × SCS Claimant",
  "Differences by South China Sea Exposure",
  "Predicted Elite Preference Distance"
)


# =====================================
# 3. 顯示圖片
# =====================================

print(p1)

print(p2)

print(p3)

print(p4)

# =====================================
# 4. 儲存圖片
# =====================================

plots <- list(
  Interaction_UNGA_Post2022 = p1,
  Interaction_UNGA_SCS = p2,
  Interaction_ISEAS_Post2022 = p3,
  Interaction_ISEAS_SCS = p4
)

for (name in names(plots)) {
  ggsave(
    filename = file.path(
      path.expand("~/Desktop/wh"),
      paste0(name, ".png")
    ),
    plot = plots[[name]],
    width = 9,
    height = 6,
    dpi = 300,
    bg = "white"
  )
}
# =====================================
# Step 13: Robustness Check
# OLS vs Country Fixed Effects
# =====================================

library(dplyr)
library(fixest)
## Warning: package 'fixest' was built under R version 4.5.2
library(modelsummary)
## Warning: package 'modelsummary' was built under R version 4.5.2
# UNGA:Country Fixed Effects
fe_unga <- feols(
  UNGA ~ Democracy + Post2022 +
    TradeChina + PolStab + FSI | Country,
  data = unga_data,
  vcov = ~ Country
)

# ISEAS:Country Fixed Effects
fe_iseas <- feols(
  ISEAS ~ Democracy + Post2022 +
    TradeChina + PolStab + FSI | Country,
  data = iseas_data,
  vcov = ~ Country
)

# 比較 OLS 與 FE
robust_models <- list(
  "UNGA OLS" = m3,
  "UNGA Country FE" = fe_unga,
  "ISEAS OLS" = m6,
  "ISEAS Country FE" = fe_iseas
)

# 顯示迴歸表
modelsummary(
  robust_models,
  vcov = list(
    sandwich::vcovCL(m3, cluster = unga_data$Country),
    ~ Country,
    sandwich::vcovCL(m6, cluster = iseas_data$Country),
    ~ Country
  ),
  coef_omit = "Intercept|SCS|USAlly",
  statistic = "({std.error})",
  stars = TRUE,
  output = "gt"
)
UNGA OLS UNGA Country FE ISEAS OLS ISEAS Country FE
Democracy -0.024* -0.022 -10.431** -9.874
(0.011) (0.035) (3.108) (19.348)
Post2022 -0.385*** -0.520*** -5.897 -9.958
(0.043) (0.064) (4.951) (8.529)
TradeChina 0.176 0.355 -60.626 3.250
(0.137) (0.263) (37.558) (56.105)
PolStab -0.003 0.013* -0.152 -0.067
(0.005) (0.005) (0.453) (1.708)
FSI -0.003 0.005 0.404 1.043
(0.003) (0.005) (0.383) (2.369)
Num.Obs. 120 120 48 48
R2 0.601 0.678 0.482 0.613
R2 Adj. 0.576 0.642 0.391 0.480
R2 Within 0.559 0.076
R2 Within Adj. 0.538 -0.056
AIC -66.2 -83.9 424.5 418.5
BIC -41.1 -47.7 441.3 442.8
Log.Lik. 42.096 -203.232
RMSE 0.17 0.15 16.69 14.44
Std.Errors Custom by: Country Custom by: Country
FE: Country X X
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
# =====================================
# Step 14: Robustness Coefficient Plot
# =====================================

library(ggplot2)
library(dplyr)
library(broom)
library(sandwich)

# 提取係數
get_robust_coef <- function(model, model_name, V = NULL) {

  if (inherits(model, "fixest")) {
    ct <- summary(model)$coeftable
    result <- data.frame(
      term = rownames(ct),
      estimate = ct[, 1],
      std.error = ct[, 2]
    )
  } else {
    ct <- lmtest::coeftest(model, vcov. = V)
    result <- broom::tidy(ct)
  }

  result %>%
    mutate(
      conf.low = estimate - qt(0.975, 7) * std.error,
      conf.high = estimate + qt(0.975, 7) * std.error,
      Model = model_name
    )
}

robust_data <- bind_rows(
  get_robust_coef(
    m3, "UNGA OLS",
    sandwich::vcovCL(m3, cluster = unga_data$Country)
  ),
  get_robust_coef(fe_unga, "UNGA Country FE"),
  get_robust_coef(
    m6, "ISEAS OLS",
    sandwich::vcovCL(m6, cluster = iseas_data$Country)
  ),
  get_robust_coef(fe_iseas, "ISEAS Country FE")
) %>%
  filter(term %in% c(
    "Democracy", "Post2022",
    "TradeChina", "PolStab", "FSI"
  )) %>%
  mutate(
    Outcome = ifelse(
      grepl("UNGA", Model),
      "UNGA Position Index",
      "ISEAS Elite Preference"
    ),
    Method = ifelse(
      grepl("Country FE", Model),
      "Country FE", "OLS"
    ),
    Variable = factor(
      term,
      levels = rev(c(
        "Democracy", "Post2022",
        "TradeChina", "PolStab", "FSI"
      )),
      labels = rev(c(
        "Democracy", "Post-2022",
        "Trade with China",
        "Political Stability", "State Capacity"
      ))
    )
  )

# 繪圖
p_robust <- ggplot(
  robust_data,
  aes(
    x = estimate,
    y = Variable,
    shape = Method,
    colour = Method
  )
) +
  geom_vline(
    xintercept = 0,
    linetype = "dashed",
    colour = "gray65"
  ) +
  geom_errorbar(
    aes(xmin = conf.low, xmax = conf.high),
    orientation = "y",
    position = position_dodge(width = 0.55),
    width = 0.2,
    linewidth = 0.7
  ) +
  geom_point(
    position = position_dodge(width = 0.55),
    size = 2.8
  ) +
  facet_wrap(
    ~ Outcome,
    scales = "free_x",
    nrow = 1
  ) +
  scale_colour_manual(
    values = c("OLS" = "gray55", "Country FE" = "black")
  ) +
  scale_shape_manual(
    values = c("OLS" = 16, "Country FE" = 17)
  ) +
  labs(
    title = "Robustness Check: OLS vs. Country Fixed Effects",
    subtitle = "Coefficient Estimates with 95% Confidence Intervals",
    x = "Coefficient Estimate",
    y = NULL,
    colour = NULL,
    shape = NULL
  ) +
  theme_classic(base_size = 14) +
  theme(
    plot.title = element_text(face = "bold", size = 18),
    plot.subtitle = element_text(colour = "gray40"),
    strip.text = element_text(face = "bold"),
    legend.position = "bottom",
    axis.text.y = element_text(size = 11)
  )

print(p_robust)

# 儲存圖片
ggsave(
  "~/Desktop/wh/ASEAN_Robustness_OLS_vs_FE.png",
  p_robust,
  width = 12,
  height = 6.5,
  dpi = 300,
  bg = "white"
)
# =========================================
# Change in Relative Position Before/After 2022
# =========================================

library(dplyr)
library(tidyr)
library(ggplot2)

# 1. 計算各國兩個時期的 UNGA 平均值
change_data <- d %>%
  filter(!is.na(UNGA)) %>%
  mutate(
    Period = ifelse(
      Year >= 2022,
      "Post-2022",
      "Pre-2022"
    ),
    Country = as.character(Country),
    Country = trimws(Country),
    Country = ifelse(
      Country == "Lao PDR", "Laos", Country
    )
  ) %>%
  group_by(Country, Period) %>%
  summarise(
    Mean_UNGA = mean(UNGA, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  pivot_wider(
    names_from = Period,
    values_from = Mean_UNGA
  ) %>%
  mutate(
    Change = `Post-2022` - `Pre-2022`,
    Country = reorder(Country, Change)
  )

# 確認八國平均值
print(change_data)
## # A tibble: 8 × 4
##   Country     `Post-2022` `Pre-2022` Change
##   <fct>             <dbl>      <dbl>  <dbl>
## 1 Cambodia          0.736      1.25  -0.510
## 2 Indonesia         0.810      1.24  -0.430
## 3 Laos              0.870      1.28  -0.406
## 4 Malaysia          0.764      1.11  -0.343
## 5 Philippines       0.565      0.962 -0.397
## 6 Singapore         0.570      0.963 -0.393
## 7 Thailand          0.629      0.917 -0.288
## 8 Vietnam           0.838      1.30  -0.461
# 2. 繪製前後比較圖
p_change <- ggplot(change_data, aes(y = Country)) +

  # 連接兩個時期的平均值
  geom_segment(
    aes(
      x = `Pre-2022`,
      xend = `Post-2022`,
      yend = Country
    ),
    color = "gray30",
    linewidth = 0.9
  ) +

  # Pre-2022:三角形
  geom_point(
    aes(x = `Pre-2022`, shape = "Pre-2022"),
    size = 3.5,
    color = "black"
  ) +

  # Post-2022:圓點
  geom_point(
    aes(x = `Post-2022`, shape = "Post-2022"),
    size = 3.5,
    color = "black"
  ) +

  scale_shape_manual(
    values = c(
      "Pre-2022" = 17,
      "Post-2022" = 16
    ),
    breaks = c("Post-2022", "Pre-2022")
  ) +

  labs(
    title = "Change in Relative Position Before and After 2022",
    subtitle = "Average UNGA Position Index across ASEAN-8, 2010–2024",
    x = "Average Relative Position Index",
    y = NULL,
    shape = "Period",
    caption = paste(
      "Pre-2022: 2010–2021 |",
      "Post-2022: 2022–2024"
    )
  ) +

  theme_classic(base_size = 14) +

  theme(
    plot.title = element_text(
      face = "bold",
      size = 18
    ),

    plot.subtitle = element_text(
      size = 12,
      color = "gray40"
    ),

    axis.text.y = element_text(
      size = 12,
      color = "black"
    ),

    axis.text.x = element_text(
      size = 11,
      color = "gray30"
    ),

    axis.title.x = element_text(
      size = 13
    ),

    legend.position = "bottom",
    legend.title = element_blank(),
    legend.text = element_text(size = 12),

    plot.caption = element_text(
      size = 10,
      color = "gray45"
    ),

    plot.margin = margin(20, 25, 15, 20)
  )

# 3. 顯示圖片
print(p_change)

# 4. 儲存高解析度圖片
ggsave(
  "~/Desktop/wh/ASEAN_Change_Pre_Post2022.png",
  plot = p_change,
  width = 10,
  height = 6.5,
  dpi = 300,
  bg = "white"
)
# =====================================
# Panel Regression: ASEAN-8
# Pooled OLS / Country FE / Random Effects
# =====================================

library(plm)
## 
## Attaching package: 'plm'
## The following objects are masked from 'package:dplyr':
## 
##     between, lag, lead
library(dplyr)
library(lmtest)
library(sandwich)

# 1. 建立 Panel Data
panel_unga <- pdata.frame(
  unga_data,
  index = c("Country", "Year")
)

panel_iseas <- pdata.frame(
  iseas_data,
  index = c("Country", "Year")
)

# 2. 設定迴歸公式
formula_panel <- function(y) {
  as.formula(paste(
    y,
    "~ Democracy + SCS + Post2022 +",
    "TradeChina + USAlly + PolStab + FSI"
  ))
}

# =====================================
# UNGA Position Index
# =====================================

# Pooled OLS
pool_unga <- plm(
  formula_panel("UNGA"),
  data = panel_unga,
  model = "pooling"
)

# Country Fixed Effects
fe_unga_panel <- plm(
  formula_panel("UNGA"),
  data = panel_unga,
  model = "within",
  effect = "individual"
)

# Random Effects
re_unga <- plm(
  formula_panel("UNGA"),
  data = panel_unga,
  model = "random",
  effect = "individual"
)

# =====================================
# ISEAS Elite Preference
# =====================================

pool_iseas <- plm(
  formula_panel("ISEAS"),
  data = panel_iseas,
  model = "pooling"
)

fe_iseas_panel <- plm(
  formula_panel("ISEAS"),
  data = panel_iseas,
  model = "within",
  effect = "individual"
)

re_iseas <- plm(
  formula_panel("ISEAS"),
  data = panel_iseas,
  model = "random",
  effect = "individual"
)

# =====================================
# 查看結果
# =====================================

summary(pool_unga)
## Pooling Model
## 
## Call:
## plm(formula = formula_panel("UNGA"), data = panel_unga, model = "pooling")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.393782 -0.109705 -0.004517  0.120269  0.431128 
## 
## Coefficients:
##               Estimate Std. Error t-value  Pr(>|t|)    
## (Intercept)  1.5403787  0.2368140  6.5046 2.259e-09 ***
## Democracy   -0.0242036  0.0156669 -1.5449    0.1252    
## SCS          0.0244431  0.0345426  0.7076    0.4807    
## Post2022    -0.3846496  0.0423930 -9.0734 4.531e-15 ***
## TradeChina   0.1759482  0.1915101  0.9187    0.3602    
## USAlly      -0.2746299  0.0582012 -4.7186 6.907e-06 ***
## PolStab     -0.0030226  0.0036441 -0.8295    0.4086    
## FSI         -0.0026084  0.0023987 -1.0874    0.2792    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    8.7287
## Residual Sum of Squares: 3.4834
## R-Squared:      0.60093
## Adj. R-Squared: 0.57598
## F-statistic: 24.0928 on 7 and 112 DF, p-value: < 2.22e-16
summary(fe_unga_panel)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = formula_panel("UNGA"), data = panel_unga, effect = "individual", 
##     model = "within")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.293815 -0.100565 -0.022286  0.102045  0.444196 
## 
## Coefficients:
##              Estimate Std. Error t-value Pr(>|t|)    
## Democracy  -0.0216439  0.0373381 -0.5797  0.56335    
## Post2022   -0.5202450  0.0526847 -9.8747  < 2e-16 ***
## TradeChina  0.3547755  0.2985557  1.1883  0.23734    
## PolStab     0.0134369  0.0056180  2.3918  0.01851 *  
## FSI         0.0047590  0.0050632  0.9399  0.34938    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    6.3746
## Residual Sum of Squares: 2.8113
## R-Squared:      0.55899
## Adj. R-Squared: 0.50954
## F-statistic: 27.1255 on 5 and 107 DF, p-value: < 2.22e-16
summary(re_unga)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = formula_panel("UNGA"), data = panel_unga, effect = "individual", 
##     model = "random")
## 
## Balanced Panel: n = 8, T = 15, N = 120
## 
## Effects:
##                   var std.dev share
## idiosyncratic 0.02627 0.16209     1
## individual    0.00000 0.00000     0
## theta: 0
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -0.393782 -0.109705 -0.004517  0.120269  0.431128 
## 
## Coefficients:
##               Estimate Std. Error z-value  Pr(>|z|)    
## (Intercept)  1.5403787  0.2368140  6.5046 7.790e-11 ***
## Democracy   -0.0242036  0.0156669 -1.5449    0.1224    
## SCS          0.0244431  0.0345426  0.7076    0.4792    
## Post2022    -0.3846496  0.0423930 -9.0734 < 2.2e-16 ***
## TradeChina   0.1759482  0.1915101  0.9187    0.3582    
## USAlly      -0.2746299  0.0582012 -4.7186 2.374e-06 ***
## PolStab     -0.0030226  0.0036441 -0.8295    0.4068    
## FSI         -0.0026084  0.0023987 -1.0874    0.2768    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    8.7287
## Residual Sum of Squares: 3.4834
## R-Squared:      0.60093
## Adj. R-Squared: 0.57598
## Chisq: 168.65 on 7 DF, p-value: < 2.22e-16
summary(pool_iseas)
## Pooling Model
## 
## Call:
## plm(formula = formula_panel("ISEAS"), data = panel_iseas, model = "pooling")
## 
## Balanced Panel: n = 8, T = 6, N = 48
## 
## Residuals:
##     Min.  1st Qu.   Median  3rd Qu.     Max. 
## -27.9045 -12.6454  -3.1519   8.6755  34.6695 
## 
## Coefficients:
##              Estimate Std. Error t-value  Pr(>|t|)    
## (Intercept)  86.81426   37.47521  2.3166 0.0257323 *  
## Democracy   -10.43121    2.80673 -3.7165 0.0006179 ***
## SCS          26.53835    5.89625  4.5009 5.719e-05 ***
## Post2022     -5.89667    5.36684 -1.0987 0.2784580    
## TradeChina  -60.62561   32.41688 -1.8702 0.0687885 .  
## USAlly       10.95056    8.42026  1.3005 0.2008722    
## PolStab      -0.15222    0.56195 -0.2709 0.7878806    
## FSI           0.40399    0.38875  1.0392 0.3049455    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    25827
## Residual Sum of Squares: 13377
## R-Squared:      0.48203
## Adj. R-Squared: 0.39139
## F-statistic: 5.31785 on 7 and 40 DF, p-value: 0.00023511
summary(fe_iseas_panel)
## Oneway (individual) effect Within Model
## 
## Call:
## plm(formula = formula_panel("ISEAS"), data = panel_iseas, effect = "individual", 
##     model = "within")
## 
## Balanced Panel: n = 8, T = 6, N = 48
## 
## Residuals:
##     Min.  1st Qu.   Median  3rd Qu.     Max. 
## -39.8742  -8.6318  -1.1209   9.1223  31.9531 
## 
## Coefficients:
##             Estimate Std. Error t-value Pr(>|t|)
## Democracy  -9.874362  18.932656 -0.5216   0.6053
## Post2022   -9.957852   8.475335 -1.1749   0.2480
## TradeChina  3.249719  53.835588  0.0604   0.9522
## PolStab    -0.066565   1.678137 -0.0397   0.9686
## FSI         1.043316   1.904118  0.5479   0.5872
## 
## Total Sum of Squares:    10830
## Residual Sum of Squares: 10004
## R-Squared:      0.076291
## Adj. R-Squared: -0.24041
## F-statistic: 0.578148 on 5 and 35 DF, p-value: 0.71634
summary(re_iseas)
## Oneway (individual) effect Random Effect Model 
##    (Swamy-Arora's transformation)
## 
## Call:
## plm(formula = formula_panel("ISEAS"), data = panel_iseas, effect = "individual", 
##     model = "random")
## 
## Balanced Panel: n = 8, T = 6, N = 48
## 
## Effects:
##                  var std.dev share
## idiosyncratic 285.82   16.91 0.415
## individual    403.62   20.09 0.585
## theta: 0.6751
## 
## Residuals:
##     Min.  1st Qu.   Median  3rd Qu.     Max. 
## -34.2206  -8.4899  -2.1782   9.5185  32.4468 
## 
## Coefficients:
##              Estimate Std. Error z-value Pr(>|z|)  
## (Intercept)  79.13036   71.72685  1.1032  0.26993  
## Democracy    -9.49836    5.53676 -1.7155  0.08625 .
## SCS          24.32131   15.50322  1.5688  0.11670  
## Post2022     -7.18624    5.07910 -1.4149  0.15711  
## TradeChina  -15.31922   46.10818 -0.3322  0.73970  
## USAlly       14.04434   22.10645  0.6353  0.52523  
## PolStab      -0.31178    1.06403 -0.2930  0.76951  
## FSI           0.48946    0.75162  0.6512  0.51491  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    12413
## Residual Sum of Squares: 10515
## R-Squared:      0.15294
## Adj. R-Squared: 0.0047001
## Chisq: 7.22195 on 7 DF, p-value: 0.40614
# =====================================
# Panel Regression Table
# =====================================

library(modelsummary)

panel_models <- list(
  "UNGA Pooled" = pool_unga,
  "UNGA FE" = fe_unga_panel,
  "UNGA RE" = re_unga,
  "ISEAS Pooled" = pool_iseas,
  "ISEAS FE" = fe_iseas_panel,
  "ISEAS RE" = re_iseas
)

# 使用按國家叢集的穩健共變異數矩陣
panel_vcov <- lapply(
  panel_models,
  function(m) {
    plm::vcovHC(
      m,
      method = "arellano",
      type = "HC1",
      cluster = "group"
    )
  }
)

coef_map <- c(
  "Democracy" = "Democracy",
  "SCS" = "SCS Claimant",
  "Post2022" = "Post-2022",
  "TradeChina" = "Trade with China",
  "USAlly" = "U.S. Formal Defense Ally",
  "PolStab" = "Political Stability",
  "FSI" = "State Capacity"
)

modelsummary(
  panel_models,
  vcov = panel_vcov,
  coef_map = coef_map,
  statistic = "({std.error})",
  estimate = "{estimate}{stars}",
  stars = c(
    "*" = 0.10,
    "**" = 0.05,
    "***" = 0.01
  ),
  fmt = 3,
  output = "gt"
)
UNGA Pooled UNGA FE UNGA RE ISEAS Pooled ISEAS FE ISEAS RE
Democracy -0.024** -0.022 -0.024** -10.431*** -9.874 -9.498**
(0.010) (0.033) (0.010) (2.938) (18.076) (4.224)
SCS Claimant 0.024 0.024 26.538*** 24.321***
(0.023) (0.023) (7.315) (7.197)
Post-2022 -0.385*** -0.520*** -0.385*** -5.897 -9.958 -7.186
(0.041) (0.059) (0.041) (4.681) (7.968) (4.580)
Trade with China 0.176 0.355 0.176 -60.626* 3.250 -15.319
(0.129) (0.246) (0.129) (35.504) (52.416) (37.521)
U.S. Formal Defense Ally -0.275*** -0.275*** 10.951 14.044
(0.071) (0.071) (10.546) (14.183)
Political Stability -0.003 0.013*** -0.003 -0.152 -0.067 -0.312
(0.004) (0.004) (0.004) (0.428) (1.596) (0.866)
State Capacity -0.003 0.005 -0.003 0.404 1.043 0.489
(0.003) (0.004) (0.003) (0.362) (2.213) (0.599)
Num.Obs. 120 120 120 48 48 48
R2 0.601 0.559 0.601 0.482 0.076 0.153
R2 Adj. 0.576 0.510 0.576 0.391 -0.240 0.005
AIC -66.2 -97.9 -66.2 424.5 404.5 412.9
BIC -41.1 -81.2 -41.1 441.3 415.7 429.7
RMSE 0.17 0.15 0.17 16.69 14.44 14.80
Std.Errors UNGA Pooled UNGA FE UNGA RE ISEAS Pooled ISEAS FE ISEAS RE
# =====================================
# Panel Model Selection Tests
# =====================================

# 1. Pooling vs Country FE
plm::pFtest(fe_unga_panel, pool_unga)
## 
##  F test for individual effects
## 
## data:  formula_panel("UNGA")
## F = 5.1165, df1 = 5, df2 = 107, p-value = 0.0003021
## alternative hypothesis: significant effects
plm::pFtest(fe_iseas_panel, pool_iseas)
## 
##  F test for individual effects
## 
## data:  formula_panel("ISEAS")
## F = 2.3607, df1 = 5, df2 = 35, p-value = 0.06015
## alternative hypothesis: significant effects
# 2. Country FE vs Random Effects
plm::phtest(fe_unga_panel, re_unga)
## 
##  Hausman Test
## 
## data:  formula_panel("UNGA")
## chisq = 28.008, df = 5, p-value = 3.626e-05
## alternative hypothesis: one model is inconsistent
plm::phtest(fe_iseas_panel, re_iseas)
## 
##  Hausman Test
## 
## data:  formula_panel("ISEAS")
## chisq = 0.63812, df = 5, p-value = 0.9862
## alternative hypothesis: one model is inconsistent
# =====================================
# Sample Period Sensitivity Analysis
# =====================================

library(dplyr)

# 舊版年份
old_sample <- unga_data %>%
  filter(Year >= 2014, Year <= 2023)

# 加入2010–2013
extended_sample <- unga_data %>%
  filter(Year <= 2023)

# 完整新版
full_sample <- unga_data

formula_test <- UNGA ~
  Democracy + SCS + Post2022 +
  TradeChina + USAlly + PolStab + FSI

# 三組相同規格的迴歸
old_model <- lm(formula_test, data = old_sample)

extended_model <- lm(
  formula_test, data = extended_sample
)

full_model <- lm(
  formula_test, data = full_sample
)

# 比較係數
modelsummary::modelsummary(
  list(
    "2014-2023" = old_model,
    "2010-2023" = extended_model,
    "2010-2024" = full_model
  ),
  vcov = list(
    sandwich::vcovCL(
      old_model, cluster = old_sample$Country, type = "HC1"
    ),
    sandwich::vcovCL(
      extended_model, cluster = extended_sample$Country, type = "HC1"
    ),
    sandwich::vcovCL(
      full_model, cluster = full_sample$Country, type = "HC1"
    )
  ),
  statistic = "({std.error})",
  stars = TRUE,
  output = "gt"
)
2014-2023 2010-2023 2010-2024
(Intercept) 1.752*** 1.545*** 1.540***
(0.188) (0.320) (0.289)
Democracy -0.028* -0.026* -0.024*
(0.012) (0.013) (0.011)
SCS 0.010 0.027 0.024
(0.017) (0.026) (0.025)
Post2022 -0.457*** -0.417*** -0.385***
(0.042) (0.044) (0.043)
TradeChina -0.156* 0.196 0.176
(0.062) (0.152) (0.137)
USAlly -0.328*** -0.277** -0.275***
(0.025) (0.083) (0.076)
PolStab -0.003 -0.003 -0.003
(0.003) (0.005) (0.005)
FSI -0.003+ -0.003 -0.003
(0.002) (0.003) (0.003)
Num.Obs. 80 112 120
R2 0.708 0.579 0.601
R2 Adj. 0.680 0.551 0.576
AIC -50.3 -56.2 -66.2
BIC -28.8 -31.7 -41.1
Log.Lik. 34.136 37.086 42.096
RMSE 0.16 0.17 0.17
Std.Errors Custom Custom Custom
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
# =====================================
# Academic Panel Regression Table
# =====================================

library(modelsummary)
library(gt)
## Warning: package 'gt' was built under R version 4.5.2
library(plm)

# 1. 六組 Panel Models
models_table <- list(
  "UNGA OLS" = pool_unga,
  "UNGA FE" = fe_unga_panel,
  "UNGA RE" = re_unga,
  "ISEAS OLS" = pool_iseas,
  "ISEAS FE" = fe_iseas_panel,
  "ISEAS RE" = re_iseas
)

# 2. Country-clustered standard errors
vcovs <- lapply(models_table, function(m) {
  plm::vcovHC(
    m,
    method = "arellano",
    type = "HC1",
    cluster = "group"
  )
})

# 3. Variable names
coef_map <- c(
  "Democracy" = "Democracy",
  "SCS" = "SCS Claimant",
  "Post2022" = "Post-2022",
  "TradeChina" = "Trade with China",
  "USAlly" = "U.S. Defense Ally",
  "PolStab" = "Political Stability",
  "FSI" = "State Capacity"
)

# 4. Academic Regression Table
tab_panel <- modelsummary(
  models_table,
  vcov = vcovs,
  coef_map = coef_map,
  estimate = "{estimate}{stars}",
  statistic = "({std.error})",
  stars = c(
    "*" = 0.10,
    "**" = 0.05,
    "***" = 0.01
  ),
  fmt = 3,
  output = "gt"
)

# 5. Academic-style formatting
tab_panel <- tab_panel %>%
  gt::tab_header(
    title = "Panel Regression Results",
    subtitle = "ASEAN-8, 2010–2024 / 2019–2024"
  ) %>%
  gt::tab_options(
    table.font.size = 13,
    table.width = gt::pct(100),
    column_labels.font.weight = "bold",
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    data_row.padding = gt::px(6)
  ) %>%
  gt::tab_source_note(
    gt::md(
      "Country-clustered HC1 standard errors in parentheses. * p < 0.10, ** p < 0.05, *** p < 0.01."
    )
  )

# 6. Display
tab_panel
Panel Regression Results
ASEAN-8, 2010–2024 / 2019–2024
UNGA OLS UNGA FE UNGA RE ISEAS OLS ISEAS FE ISEAS RE
Democracy -0.024** -0.022 -0.024** -10.431*** -9.874 -9.498**
(0.010) (0.033) (0.010) (2.938) (18.076) (4.224)
SCS Claimant 0.024 0.024 26.538*** 24.321***
(0.023) (0.023) (7.315) (7.197)
Post-2022 -0.385*** -0.520*** -0.385*** -5.897 -9.958 -7.186
(0.041) (0.059) (0.041) (4.681) (7.968) (4.580)
Trade with China 0.176 0.355 0.176 -60.626* 3.250 -15.319
(0.129) (0.246) (0.129) (35.504) (52.416) (37.521)
U.S. Defense Ally -0.275*** -0.275*** 10.951 14.044
(0.071) (0.071) (10.546) (14.183)
Political Stability -0.003 0.013*** -0.003 -0.152 -0.067 -0.312
(0.004) (0.004) (0.004) (0.428) (1.596) (0.866)
State Capacity -0.003 0.005 -0.003 0.404 1.043 0.489
(0.003) (0.004) (0.003) (0.362) (2.213) (0.599)
Num.Obs. 120 120 120 48 48 48
R2 0.601 0.559 0.601 0.482 0.076 0.153
R2 Adj. 0.576 0.510 0.576 0.391 -0.240 0.005
AIC -66.2 -97.9 -66.2 424.5 404.5 412.9
BIC -41.1 -81.2 -41.1 441.3 415.7 429.7
RMSE 0.17 0.15 0.17 16.69 14.44 14.80
Std.Errors UNGA OLS UNGA FE UNGA RE ISEAS OLS ISEAS FE ISEAS RE
Country-clustered HC1 standard errors in parentheses. * p < 0.10, ** p < 0.05, *** p < 0.01.
# 7. Save
gt::gtsave(
  tab_panel,
  "~/Desktop/wh/ASEAN_Panel_Regression.html"
)
# =====================================
# Complete Panel Regression Table
# =====================================

library(modelsummary)
library(gt)
library(plm)

# 六組模型
models_table <- list(
  "UNGA OLS" = pool_unga,
  "UNGA FE" = fe_unga_panel,
  "UNGA RE" = re_unga,
  "ISEAS OLS" = pool_iseas,
  "ISEAS FE" = fe_iseas_panel,
  "ISEAS RE" = re_iseas
)

# 國家叢集標準誤
vcovs <- lapply(models_table, function(m) {
  plm::vcovHC(
    m,
    method = "arellano",
    type = "HC1",
    cluster = "group"
  )
})

# 完整變數名稱及排列順序
coef_map <- c(
  "Democracy" = "Democracy",
  "SCS" = "SCS Claimant",
  "Post2022" = "Post-2022",
  "TradeChina" = "Trade with China",
  "USAlly" = "U.S. Formal Defense Ally",
  "PolStab" = "Political Stability",
  "FSI" = "State Capacity (100 - FSI)",
  "(Intercept)" = "Constant"
)

# 模型統計資訊
gof_map <- data.frame(
  raw = c("nobs", "r.squared", "adj.r.squared"),
  clean = c("Observations", "R-squared", "Adjusted R-squared"),
  fmt = c(0, 3, 3)
)

# 產生完整回歸表
tab_panel <- modelsummary(
  models_table,
  vcov = vcovs,
  coef_map = coef_map,
  gof_map = gof_map,
  estimate = "{estimate}{stars}",
  statistic = "({std.error})",
  stars = c(
    "*" = 0.10,
    "**" = 0.05,
    "***" = 0.01
  ),
  fmt = 3,
  output = "gt"
)

# 美化
tab_panel <- tab_panel |>
  gt::tab_header(
    title = "Panel Regression Results",
    subtitle = "ASEAN-8: UNGA and ISEAS"
  ) |>
  gt::tab_options(
    table.font.size = 13,
    table.width = gt::pct(100),
    column_labels.font.weight = "bold",
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    data_row.padding = gt::px(7)
  ) |>
  gt::tab_source_note(
    gt::md(
      "Country-clustered HC1 standard errors in parentheses. * p < 0.10, ** p < 0.05, *** p < 0.01."
    )
  ) |>
  gt::tab_source_note(
    gt::md(
      "SCS and U.S. alliance status are absorbed by country fixed effects."
    )
  )

# 顯示表格
tab_panel
Panel Regression Results
ASEAN-8: UNGA and ISEAS
UNGA OLS UNGA FE UNGA RE ISEAS OLS ISEAS FE ISEAS RE
Democracy -0.024** -0.022 -0.024** -10.431*** -9.874 -9.498**
(0.010) (0.033) (0.010) (2.938) (18.076) (4.224)
SCS Claimant 0.024 0.024 26.538*** 24.321***
(0.023) (0.023) (7.315) (7.197)
Post-2022 -0.385*** -0.520*** -0.385*** -5.897 -9.958 -7.186
(0.041) (0.059) (0.041) (4.681) (7.968) (4.580)
Trade with China 0.176 0.355 0.176 -60.626* 3.250 -15.319
(0.129) (0.246) (0.129) (35.504) (52.416) (37.521)
U.S. Formal Defense Ally -0.275*** -0.275*** 10.951 14.044
(0.071) (0.071) (10.546) (14.183)
Political Stability -0.003 0.013*** -0.003 -0.152 -0.067 -0.312
(0.004) (0.004) (0.004) (0.428) (1.596) (0.866)
State Capacity (100 - FSI) -0.003 0.005 -0.003 0.404 1.043 0.489
(0.003) (0.004) (0.003) (0.362) (2.213) (0.599)
Constant 1.540*** 1.540*** 86.814*** 79.130
(0.272) (0.272) (31.132) (61.613)
Observations 120 120 120 48 48 48
R-squared 0.601 0.559 0.601 0.482 0.076 0.153
Adjusted R-squared 0.576 0.510 0.576 0.391 -0.240 0.005
Country-clustered HC1 standard errors in parentheses. * p < 0.10, ** p < 0.05, *** p < 0.01.
SCS and U.S. alliance status are absorbed by country fixed effects.
# 儲存 HTML
gt::gtsave(
  tab_panel,
  "~/Desktop/wh/ASEAN_Panel_Regression_Complete.html"
)
# ============================================================
# ASEAN Multicollinearity Analysis (VIF)
# Data: Asean1029.xlsx
# ============================================================

# 1. 安裝與載入套件
packages <- c("readxl", "dplyr", "car", "tidyr")

for (p in packages) {
  if (!requireNamespace(p, quietly = TRUE)) {
    install.packages(p)
  }
}

library(readxl)
library(dplyr)
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
library(tidyr)


# 2. 讀取資料
# 如果檔案不在此位置,請修改路徑
file_path <- "~/Desktop/wh/Asean1029.xlsx"

raw <- read_excel(file_path, .name_repair = "unique")
## New names:
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...13`
## • `Trade China GDP ratio old` -> `Trade China GDP ratio old...14`
# 檢查原始欄位
print(names(raw))
##  [1] "Country"                        "ISO3"                          
##  [3] "Year"                           "UNGA Normalized Gap"           
##  [5] "UNGA Position Index"            "ISEAS Elite preference"        
##  [7] "Political Stability"            "FSI  (100 - raw FSI)"          
##  [9] "Democracy EIU"                  "Post2022"                      
## [11] "SCS"                            "US Formal Defense Ally (1/0)"  
## [13] "Trade China GDP ratio old...13" "Trade China GDP ratio old...14"
# 3. 整理變數
# 依照 Asean1029.xlsx 的欄位位置

d <- data.frame(
  Country    = as.character(raw[[1]]),
  Year       = as.integer(raw[[3]]),
  UNGA       = as.numeric(raw[[5]]),
  ISEAS      = as.numeric(raw[[6]]),
  PolStab    = as.numeric(raw[[7]]),
  FSI        = as.numeric(raw[[8]]),
  Democracy  = as.numeric(raw[[9]]),
  Post2022   = as.numeric(raw[[10]]),
  SCS        = as.numeric(raw[[11]]),
  USAlly     = as.numeric(raw[[12]]),
  TradeChina = as.numeric(raw[[14]])
)


# 4. 設定三組模型

# Core Model:核心解釋變數
core_vars <- c(
  "Democracy",
  "SCS",
  "Post2022"
)

# Main Model:核心變數 + 主要控制變數
main_vars <- c(
  core_vars,
  "TradeChina",
  "USAlly"
)

# Full Model:加入政治穩定與 FSI
full_vars <- c(
  main_vars,
  "PolStab",
  "FSI"
)


# 5. 建立 VIF 計算函數

run_vif <- function(data, dv, vars, model_name) {

  # 使用該模型所有變數皆非缺失的樣本
  model_data <- data %>%
    select(all_of(c(dv, vars))) %>%
    drop_na()

  # 建立迴歸公式
  formula <- as.formula(
    paste(dv, "~", paste(vars, collapse = " + "))
  )

  # 執行 OLS
  model <- lm(formula, data = model_data)

  # 計算 VIF
  vif_values <- car::vif(model)

  # 整理結果
  result <- data.frame(
    DV = dv,
    Model = model_name,
    Variable = names(vif_values),
    VIF = as.numeric(vif_values),
    Tolerance = 1 / as.numeric(vif_values),
    N = nrow(model_data)
  )

  return(result)
}


# 6. UNGA 三組模型

vif_unga_core <- run_vif(
  d, "UNGA", core_vars, "Core"
)

vif_unga_main <- run_vif(
  d, "UNGA", main_vars, "Main"
)

vif_unga_full <- run_vif(
  d, "UNGA", full_vars, "Full"
)


# 7. ISEAS 三組模型

vif_iseas_core <- run_vif(
  d, "ISEAS", core_vars, "Core"
)

vif_iseas_main <- run_vif(
  d, "ISEAS", main_vars, "Main"
)

vif_iseas_full <- run_vif(
  d, "ISEAS", full_vars, "Full"
)


# 8. 合併所有結果

vif_results <- bind_rows(
  vif_unga_core,
  vif_unga_main,
  vif_unga_full,
  vif_iseas_core,
  vif_iseas_main,
  vif_iseas_full
)


# 9. 顯示完整結果

print(vif_results, row.names = FALSE)
##     DV Model   Variable      VIF Tolerance   N
##   UNGA  Core  Democracy 1.022160 0.9783199 120
##   UNGA  Core        SCS 1.021898 0.9785717 120
##   UNGA  Core   Post2022 1.000263 0.9997371 120
##   UNGA  Main  Democracy 1.306630 0.7653279 120
##   UNGA  Main        SCS 1.049774 0.9525857 120
##   UNGA  Main   Post2022 1.086184 0.9206546 120
##   UNGA  Main TradeChina 1.443607 0.6927094 120
##   UNGA  Main     USAlly 1.285045 0.7781827 120
##   UNGA  Full  Democracy 2.998901 0.3334555 120
##   UNGA  Full        SCS 1.078995 0.9267884 120
##   UNGA  Full   Post2022 1.109441 0.9013544 120
##   UNGA  Full TradeChina 1.868316 0.5352412 120
##   UNGA  Full     USAlly 2.450540 0.4080733 120
##   UNGA  Full    PolStab 8.085307 0.1236811 120
##   UNGA  Full        FSI 6.385131 0.1566139 120
##  ISEAS  Core  Democracy 1.037861 0.9635197  48
##  ISEAS  Core        SCS 1.037859 0.9635221  48
##  ISEAS  Core   Post2022 1.000003 0.9999974  48
##  ISEAS  Main  Democracy 1.866237 0.5358377  48
##  ISEAS  Main        SCS 1.114936 0.8969128  48
##  ISEAS  Main   Post2022 1.027513 0.9732239  48
##  ISEAS  Main TradeChina 2.032861 0.4919175  48
##  ISEAS  Main     USAlly 1.353799 0.7386622  48
##  ISEAS  Full  Democracy 4.448845 0.2247774  48
##  ISEAS  Full        SCS 1.169485 0.8550776  48
##  ISEAS  Full   Post2022 1.033495 0.9675909  48
##  ISEAS  Full TradeChina 2.268942 0.4407341  48
##  ISEAS  Full     USAlly 1.908023 0.5241027  48
##  ISEAS  Full    PolStab 6.194522 0.1614330  48
##  ISEAS  Full        FSI 6.045584 0.1654100  48
# 10. 製作適合論文的 VIF 比較表

vif_table <- vif_results %>%
  mutate(
    Model = paste(DV, Model, sep = "_"),
    VIF = round(VIF, 3)
  ) %>%
  select(Variable, Model, VIF) %>%
  pivot_wider(
    names_from = Model,
    values_from = VIF
  )

print(vif_table, width = Inf)
## # A tibble: 7 × 7
##   Variable   UNGA_Core UNGA_Main UNGA_Full ISEAS_Core ISEAS_Main ISEAS_Full
##   <chr>          <dbl>     <dbl>     <dbl>      <dbl>      <dbl>      <dbl>
## 1 Democracy       1.02      1.31      3.00       1.04       1.87       4.45
## 2 SCS             1.02      1.05      1.08       1.04       1.12       1.17
## 3 Post2022        1         1.09      1.11       1          1.03       1.03
## 4 TradeChina     NA         1.44      1.87      NA          2.03       2.27
## 5 USAlly         NA         1.28      2.45      NA          1.35       1.91
## 6 PolStab        NA        NA         8.09      NA         NA          6.20
## 7 FSI            NA        NA         6.38      NA         NA          6.05
# 11. 匯出 CSV

write.csv(
  vif_results,
  "ASEAN_VIF_Results.csv",
  row.names = FALSE
)

write.csv(
  vif_table,
  "ASEAN_VIF_Table.csv",
  row.names = FALSE
)