hedging data

library(readxl)
library(tidyverse)
Warning: package 'ggplot2' was built under R version 4.5.2
Warning: package 'tidyr' was built under R version 4.5.2
Warning: package 'purrr' was built under R version 4.5.2
Warning: package 'dplyr' was built under R version 4.5.2
Warning: package 'lubridate' was built under R version 4.5.2
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.0     ✔ readr     2.1.5
✔ forcats   1.0.1     ✔ stringr   1.5.2
✔ ggplot2   4.0.2     ✔ tibble    3.3.0
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(plm)

Attaching package: 'plm'

The following objects are masked from 'package:dplyr':

    between, lag, lead
# 重新讀取資料
df <- read_excel("~/Desktop/data/hedging.data.xlsx",
                 sheet = "hedging csv")

# 檢查欄位名稱
names(df)
 [1] "Country"             "Year"                "Political stability"
 [4] "Democracy"           "Post 2019"           "Post2022"           
 [7] "SCS"                 "Trade China"         "Sec us"             
[10] "Strategic Ambiguity" "Dis unga idealpoint"
df <- df %>%
  rename(
    political_stability = `Political stability`,
    post2019 = `Post 2019`,
    post2022 = Post2022,
    scs = SCS,
    trade_china = `Trade China`,
    sec_us = `Sec us`,
    strategic_ambiguity = `Strategic Ambiguity`,
    unga_idealpoint = `Dis unga idealpoint`
  )
df <- df %>%
  mutate(
    Country = as.factor(Country),
    Year = as.numeric(Year),
    political_stability = as.numeric(political_stability),
    Democracy = as.numeric(Democracy),
    post2019 = as.numeric(post2019),
    post2022 = as.numeric(post2022),
    scs = as.numeric(scs),
    trade_china = as.numeric(trade_china),
    sec_us = as.numeric(sec_us),
    strategic_ambiguity = as.numeric(strategic_ambiguity),
    unga_idealpoint = as.numeric(unga_idealpoint)
  )
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `strategic_ambiguity = as.numeric(strategic_ambiguity)`.
Caused by warning:
! NAs introduced by coercion
p_df <- pdata.frame(df, index = c("Country", "Year"))
m_sa_ols <- lm(
  strategic_ambiguity ~ 
    political_stability + Democracy + post2019 + post2022 +
    scs + trade_china + sec_us,
  data = df
)

summary(m_sa_ols)

Call:
lm(formula = strategic_ambiguity ~ political_stability + Democracy + 
    post2019 + post2022 + scs + trade_china + sec_us, data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.981 -11.525   3.415  10.097  34.846 

Coefficients: (1 not defined because of singularities)
                     Estimate Std. Error t value Pr(>|t|)   
(Intercept)          10.90526   33.88994   0.322  0.74965   
political_stability   0.09247    0.35986   0.257  0.79881   
Democracy             7.15807    2.06864   3.460  0.00151 **
post2019                   NA         NA      NA       NA   
post2022              9.17089    6.69806   1.369  0.18019   
scs                 -17.90746    7.99031  -2.241  0.03186 * 
trade_china          16.91539   35.52276   0.476  0.63708   
sec_us               24.77442   24.59066   1.007  0.32104   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 20.35 on 33 degrees of freedom
  (40 observations deleted due to missingness)
Multiple R-squared:  0.3808,    Adjusted R-squared:  0.2682 
F-statistic: 3.382 on 6 and 33 DF,  p-value: 0.01038
m_sa_fe <- plm(
  strategic_ambiguity ~ 
    political_stability + Democracy + post2019 + post2022 +
    scs + trade_china + sec_us,
  data = p_df,
  model = "within",
  effect = "individual"
)

summary(m_sa_fe)
Oneway (individual) effect Within Model

Call:
plm(formula = strategic_ambiguity ~ political_stability + Democracy + 
    post2019 + post2022 + scs + trade_china + sec_us, data = p_df, 
    effect = "individual", model = "within")

Balanced Panel: n = 8, T = 5, N = 40

Residuals:
    Min.  1st Qu.   Median  3rd Qu.     Max. 
-24.5312  -7.9180  -1.5057   6.8502  36.2259 

Coefficients:
                      Estimate Std. Error t-value Pr(>|t|)
political_stability  -0.098144   1.856343 -0.0529   0.9582
Democracy            -0.964403  14.124433 -0.0683   0.9461
post2022              9.597447   6.389506  1.5021   0.1447
trade_china          21.596008 102.683983  0.2103   0.8350
sec_us                9.943919  25.375631  0.3919   0.6982

Total Sum of Squares:    7958.8
Residual Sum of Squares: 6891.2
R-Squared:      0.13413
Adj. R-Squared: -0.2507
F-statistic: 0.836518 on 5 and 27 DF, p-value: 0.53545
m_unga_ols <- lm(
  unga_idealpoint ~ 
    political_stability + Democracy + post2019 + post2022 +
    scs + trade_china + sec_us,
  data = df
)

summary(m_unga_ols)

Call:
lm(formula = unga_idealpoint ~ political_stability + Democracy + 
    post2019 + post2022 + scs + trade_china + sec_us, data = df)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.09776 -0.21588  0.01993  0.24952  0.68275 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)          3.2404224  0.3755920   8.628 1.03e-12 ***
political_stability  0.0008829  0.0038731   0.228    0.820    
Democracy           -0.1145093  0.0239806  -4.775 9.18e-06 ***
post2019            -0.0266826  0.0866581  -0.308    0.759    
post2022            -1.1710189  0.1084542 -10.797  < 2e-16 ***
scs                  0.1973086  0.0867966   2.273    0.026 *  
trade_china         -0.0346633  0.4187821  -0.083    0.934    
sec_us               0.2052392  0.2991154   0.686    0.495    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.3325 on 72 degrees of freedom
Multiple R-squared:  0.7211,    Adjusted R-squared:  0.694 
F-statistic: 26.59 on 7 and 72 DF,  p-value: < 2.2e-16
library(readxl)
library(tidyverse)
library(broom)
library(modelsummary)
Warning: package 'modelsummary' was built under R version 4.5.2
library(ggplot2)

# 讀取資料
df <- read_excel("~/Desktop/data/hedging.data.xlsx",
                 sheet = "hedging csv")

# 看欄位
names(df)
 [1] "Country"             "Year"                "Political stability"
 [4] "Democracy"           "Post 2019"           "Post2022"           
 [7] "SCS"                 "Trade China"         "Sec us"             
[10] "Strategic Ambiguity" "Dis unga idealpoint"
# 重新命名欄位
df <- df %>%
  rename(
    political_stability = `Political stability`,
    post2019 = `Post 2019`,
    post2022 = Post2022,
    scs = SCS,
    trade_china = `Trade China`,
    sec_us = `Sec us`,
    strategic_ambiguity = `Strategic Ambiguity`,
    unga_idealpoint = `Dis unga idealpoint`
  )

# 轉成數值
df <- df %>%
  mutate(
    Year = as.numeric(Year),
    political_stability = as.numeric(political_stability),
    Democracy = as.numeric(Democracy),
    post2019 = as.numeric(post2019),
    post2022 = as.numeric(post2022),
    scs = as.numeric(scs),
    trade_china = as.numeric(trade_china),
    sec_us = as.numeric(sec_us),
    strategic_ambiguity = as.numeric(strategic_ambiguity),
    unga_idealpoint = as.numeric(unga_idealpoint)
  )
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `strategic_ambiguity = as.numeric(strategic_ambiguity)`.
Caused by warning:
! NAs introduced by coercion
summary(df$strategic_ambiguity)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  26.80   44.20   77.60   67.62   88.65   96.00      40 
summary(df$unga_idealpoint)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.038   2.397   2.832   2.683   3.154   3.492 
sum(is.na(df$strategic_ambiguity))
[1] 40
sum(is.na(df$unga_idealpoint))
[1] 0
# 策略模糊模型資料
df_sa <- df %>%
  filter(!is.na(strategic_ambiguity))

# UNGA 模型資料
df_unga <- df %>%
  filter(!is.na(unga_idealpoint))
# DV 1:策略模糊
model_sa <- lm(
  strategic_ambiguity ~ 
    political_stability + Democracy + post2022 +
    scs + trade_china + sec_us,
  data = df_sa
)

summary(model_sa)

Call:
lm(formula = strategic_ambiguity ~ political_stability + Democracy + 
    post2022 + scs + trade_china + sec_us, data = df_sa)

Residuals:
    Min      1Q  Median      3Q     Max 
-42.981 -11.525   3.415  10.097  34.846 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)   
(Intercept)          10.90526   33.88994   0.322  0.74965   
political_stability   0.09247    0.35986   0.257  0.79881   
Democracy             7.15807    2.06864   3.460  0.00151 **
post2022              9.17089    6.69806   1.369  0.18019   
scs                 -17.90746    7.99031  -2.241  0.03186 * 
trade_china          16.91539   35.52276   0.476  0.63708   
sec_us               24.77442   24.59066   1.007  0.32104   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 20.35 on 33 degrees of freedom
Multiple R-squared:  0.3808,    Adjusted R-squared:  0.2682 
F-statistic: 3.382 on 6 and 33 DF,  p-value: 0.01038
# DV 2:UNGA 理想點距離
model_unga <- lm(
  unga_idealpoint ~ 
    political_stability + Democracy + post2019 + post2022 +
    scs + trade_china + sec_us,
  data = df_unga
)

summary(model_unga)

Call:
lm(formula = unga_idealpoint ~ political_stability + Democracy + 
    post2019 + post2022 + scs + trade_china + sec_us, data = df_unga)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.09776 -0.21588  0.01993  0.24952  0.68275 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)          3.2404224  0.3755920   8.628 1.03e-12 ***
political_stability  0.0008829  0.0038731   0.228    0.820    
Democracy           -0.1145093  0.0239806  -4.775 9.18e-06 ***
post2019            -0.0266826  0.0866581  -0.308    0.759    
post2022            -1.1710189  0.1084542 -10.797  < 2e-16 ***
scs                  0.1973086  0.0867966   2.273    0.026 *  
trade_china         -0.0346633  0.4187821  -0.083    0.934    
sec_us               0.2052392  0.2991154   0.686    0.495    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.3325 on 72 degrees of freedom
Multiple R-squared:  0.7211,    Adjusted R-squared:  0.694 
F-statistic: 26.59 on 7 and 72 DF,  p-value: < 2.2e-16
model_sa

Call:
lm(formula = strategic_ambiguity ~ political_stability + Democracy + 
    post2022 + scs + trade_china + sec_us, data = df_sa)

Coefficients:
        (Intercept)  political_stability            Democracy  
           10.90526              0.09247              7.15807  
           post2022                  scs          trade_china  
            9.17089            -17.90746             16.91539  
             sec_us  
           24.77442  
model_unga

Call:
lm(formula = unga_idealpoint ~ political_stability + Democracy + 
    post2019 + post2022 + scs + trade_china + sec_us, data = df_unga)

Coefficients:
        (Intercept)  political_stability            Democracy  
          3.2404224            0.0008829           -0.1145093  
           post2019             post2022                  scs  
         -0.0266826           -1.1710189            0.1973086  
        trade_china               sec_us  
         -0.0346633            0.2052392  
coef_all <- bind_rows(
  tidy(model_sa, conf.int = TRUE) %>%
    mutate(model = "策略模糊\nStrategic Ambiguity"),
  tidy(model_unga, conf.int = TRUE) %>%
    mutate(model = "UNGA 理想點距離\nUNGA Ideal Point")
) %>%
  filter(term != "(Intercept)") %>%
  mutate(
    term_label = case_when(
      term == "political_stability" ~ "政治穩定度",
      term == "Democracy" ~ "民主指數",
      term == "post2019" ~ "Post-2019",
      term == "post2022" ~ "Post-2022",
      term == "scs" ~ "南海聲索國",
      term == "trade_china" ~ "對中國經濟依賴",
      term == "sec_us" ~ "對美軍事合作",
      TRUE ~ term
    ),
    term_label = factor(
      term_label,
      levels = c(
        "政治穩定度",
        "民主指數",
        "Post-2019",
        "Post-2022",
        "南海聲索國",
        "對中國經濟依賴",
        "對美軍事合作"
      )
    )
  )

coef_plot <- ggplot(coef_all, aes(x = estimate, y = term_label)) +
  geom_point(size = 3) +
  geom_errorbarh(
    aes(xmin = conf.low, xmax = conf.high),
    height = 0.2,
    linewidth = 0.8
  ) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  facet_wrap(~ model, scales = "free_x") +
  labs(
    title = "Regression Coefficient Plot",
    subtitle = "Two Dependent Variables",
    x = "Coefficient Estimate with 95% Confidence Interval",
    y = NULL
  ) +
  theme_minimal(base_size = 15) +
  theme(
    plot.title = element_text(face = "bold", size = 18),
    plot.subtitle = element_text(size = 12),
    strip.text = element_text(face = "bold", size = 13),
    axis.text.y = element_text(size = 12),
    legend.position = "none"
  )
Warning: `geom_errorbarh()` was deprecated in ggplot2 4.0.0.
ℹ Please use the `orientation` argument of `geom_errorbar()` instead.
coef_plot
`height` was translated to `width`.

library(tidyverse)
library(broom)
library(ggplot2)

# =========================
# 1. 建立兩個模型資料
# =========================

df_sa <- df %>%
  filter(!is.na(strategic_ambiguity))

df_unga <- df %>%
  filter(!is.na(unga_idealpoint))

# =========================
# 2. 標準化變數
# =========================

df_sa_z <- df_sa %>%
  mutate(
    strategic_ambiguity_z = as.numeric(scale(strategic_ambiguity)),
    political_stability_z = as.numeric(scale(political_stability)),
    Democracy_z = as.numeric(scale(Democracy)),
    trade_china_z = as.numeric(scale(trade_china)),
    sec_us_z = as.numeric(scale(sec_us))
  )

df_unga_z <- df_unga %>%
  mutate(
    unga_idealpoint_z = as.numeric(scale(unga_idealpoint)),
    political_stability_z = as.numeric(scale(political_stability)),
    Democracy_z = as.numeric(scale(Democracy)),
    trade_china_z = as.numeric(scale(trade_china)),
    sec_us_z = as.numeric(scale(sec_us))
  )

# =========================
# 3. 跑標準化回歸
# =========================

model_sa_z <- lm(
  strategic_ambiguity_z ~ 
    political_stability_z + Democracy_z + post2022 +
    scs + trade_china_z + sec_us_z,
  data = df_sa_z
)

model_unga_z <- lm(
  unga_idealpoint_z ~ 
    political_stability_z + Democracy_z + post2019 + post2022 +
    scs + trade_china_z + sec_us_z,
  data = df_unga_z
)

# =========================
# 4. 整理係數
# =========================

coef_all_z <- bind_rows(
  tidy(model_sa_z, conf.int = TRUE) %>%
    mutate(model = "策略模糊"),
  tidy(model_unga_z, conf.int = TRUE) %>%
    mutate(model = "UNGA 理想點")
) %>%
  filter(term != "(Intercept)") %>%
  mutate(
    term_label = case_when(
      term == "political_stability_z" ~ "政治穩定度",
      term == "Democracy_z" ~ "民主指數",
      term == "post2019" ~ "Post-2019",
      term == "post2022" ~ "Post-2022",
      term == "scs" ~ "南海聲索國",
      term == "trade_china_z" ~ "對中國經濟依賴",
      term == "sec_us_z" ~ "對美軍事合作",
      TRUE ~ term
    ),
    term_label = factor(
      term_label,
      levels = rev(c(
        "政治穩定度",
        "民主指數",
        "Post-2019",
        "Post-2022",
        "南海聲索國",
        "對中國經濟依賴",
        "對美軍事合作"
      ))
    ),
    model = factor(
      model,
      levels = c("策略模糊", "UNGA 理想點")
    )
  )

# =========================
# 5. 畫在同一個 panel
# =========================

coef_plot_one_panel <- ggplot(
  coef_all_z,
  aes(x = estimate, y = term_label, shape = model)
) +
  geom_vline(xintercept = 0, linetype = "dashed", linewidth = 0.7) +
  geom_errorbarh(
    aes(xmin = conf.low, xmax = conf.high),
    position = position_dodge(width = 0.6),
    height = 0.2,
    linewidth = 0.8
  ) +
  geom_point(
    position = position_dodge(width = 0.6),
    size = 3
  ) +
  labs(
    title = "Regression Coefficient Plot",
    subtitle = "Standardized coefficients for two dependent variables",
    x = "Standardized Coefficient Estimate",
    y = NULL,
    shape = "Dependent Variable"
  ) +
  theme_minimal(base_size = 15) +
  theme(
    plot.title = element_text(face = "bold", size = 18),
    plot.subtitle = element_text(size = 12),
    axis.text.y = element_text(size = 12),
    legend.position = "bottom",
    legend.title = element_text(face = "bold")
  )

coef_plot_one_panel
`height` was translated to `width`.

ggsave(
  "one_panel_two_dv_coefficient_plot.png",
  coef_plot_one_panel,
  width = 11,
  height = 7,
  dpi = 300
)
`height` was translated to `width`.
coef_plot <- ggplot(coef_all, aes(x = estimate, y = term_label)) +
  geom_point(size = 3) +
  geom_errorbarh(
    aes(xmin = conf.low, xmax = conf.high),
    height = 0.2,
    linewidth = 0.8
  ) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  facet_wrap(~ model, scales = "free_x") +
  labs(
    title = "Regression Coefficient Plot",
    subtitle = "Two Dependent Variables",
    x = "Coefficient Estimate with 95% Confidence Interval",
    y = NULL
  ) +
  theme_minimal(base_size = 15, base_family = "PingFang TC") +
  theme(
    plot.title = element_text(face = "bold", size = 18),
    plot.subtitle = element_text(size = 12),
    strip.text = element_text(face = "bold", size = 13),
    axis.text.y = element_text(size = 12),
    legend.position = "none"
  )

coef_plot
`height` was translated to `width`.

ggplot(df, aes(x = Year, y = strategic_ambiguity, group = Country, color = Country)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  geom_vline(xintercept = 2022, linetype = "dashed") +
  labs(
    title = "Strategic Ambiguity over Time",
    subtitle = "ISEAS-based elite attitude measure",
    x = "Year",
    y = "Strategic Ambiguity"
  ) +
  theme_minimal(base_size = 14)
Warning: Removed 40 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 40 rows containing missing values or values outside the scale range
(`geom_point()`).

ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = factor(post2022), y = strategic_ambiguity)) +
  geom_boxplot(width = 0.5, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.6, size = 2) +
  labs(
    title = "Strategic Ambiguity before and after 2022",
    x = "Post-2022",
    y = "Strategic Ambiguity"
  ) +
  scale_x_discrete(labels = c("0" = "Before 2022", "1" = "After 2022")) +
  theme_minimal(base_size = 14)

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = factor(post2022), y = unga_idealpoint)) +
  geom_boxplot(width = 0.5, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.6, size = 2) +
  labs(
    title = "UNGA Ideal Point Distance before and after 2022",
    subtitle = "Lower values indicate stronger hedging",
    x = "Post-2022",
    y = "UNGA Ideal Point Distance"
  ) +
  scale_x_discrete(labels = c("0" = "Before 2022", "1" = "After 2022")) +
  theme_minimal(base_size = 14)

ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = Democracy, y = strategic_ambiguity)) +
  geom_point(size = 2.5, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Democracy and Strategic Ambiguity",
    x = "Democracy Index",
    y = "Strategic Ambiguity"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = Democracy, y = unga_idealpoint)) +
  geom_point(size = 2.5, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Democracy and UNGA Ideal Point Distance",
    subtitle = "Lower values indicate stronger hedging",
    x = "Democracy Index",
    y = "UNGA Ideal Point Distance"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = Democracy, y = unga_idealpoint)) +
  geom_point(size = 2.5, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Democracy and UNGA Ideal Point Distance",
    subtitle = "Lower values indicate stronger hedging",
    x = "Democracy Index",
    y = "UNGA Ideal Point Distance"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = factor(scs), y = unga_idealpoint)) +
  geom_boxplot(width = 0.5, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.6, size = 2) +
  labs(
    title = "UNGA Ideal Point Distance by SCS Claimant Status",
    subtitle = "Lower values indicate stronger hedging",
    x = "SCS Claimant",
    y = "UNGA Ideal Point Distance"
  ) +
  scale_x_discrete(labels = c("0" = "Non-claimant", "1" = "Claimant")) +
  theme_minimal(base_size = 14)

ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = factor(scs), y = strategic_ambiguity)) +
  geom_boxplot(width = 0.5, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.6, size = 2) +
  labs(
    title = "Strategic Ambiguity by SCS Claimant Status",
    x = "SCS Claimant",
    y = "Strategic Ambiguity"
  ) +
  scale_x_discrete(labels = c("0" = "Non-claimant", "1" = "Claimant")) +
  theme_minimal(base_size = 14)

ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = Democracy, y = strategic_ambiguity, color = Country)) +
  geom_point(size = 3, alpha = 0.8) +
  geom_smooth(
    aes(group = 1),
    method = "lm",
    se = TRUE,
    color = "black"
  ) +
  labs(
    title = "Democracy and Strategic Ambiguity",
    x = "Democracy Index",
    y = "Strategic Ambiguity",
    color = "Country"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

# =========================
# 1. 載入套件
# =========================
library(tidyverse)
library(broom)

# =========================
# 2. 建立兩個回歸模型
# =========================

model_unga <- lm(
  unga_idealpoint ~ political_stability + Democracy +
    post2019 + post2022 + scs + trade_china + sec_us,
  data = df_unga
)

model_sa <- lm(
  strategic_ambiguity ~ political_stability + Democracy +
    post2022 + scs + trade_china + sec_us,
  data = df_sa
)

# =========================
# 3. 整理模型結果
# =========================

coef_unga <- tidy(model_unga, conf.int = TRUE) %>%
  mutate(model = "UNGA Ideal Point Distance")

coef_sa <- tidy(model_sa, conf.int = TRUE) %>%
  mutate(model = "Strategic Ambiguity")

coef_all <- bind_rows(coef_unga, coef_sa) %>%
  filter(term != "(Intercept)") %>%
  mutate(
    term_label = recode(
      term,
      "political_stability" = "政治穩定度",
      "Democracy" = "民主指數",
      "post2019" = "Post-2019",
      "post2022" = "Post-2022",
      "scs" = "南海聲索國",
      "trade_china" = "對中國經濟依賴",
      "sec_us" = "對美軍事合作"
    ),
    term_label = factor(
      term_label,
      levels = c(
        "對美軍事合作",
        "對中國經濟依賴",
        "南海聲索國",
        "Post-2022",
        "Post-2019",
        "民主指數",
        "政治穩定度"
      )
    )
  )

# =========================
# 4. 畫合併回歸係數圖
# =========================

ggplot(coef_all, aes(x = estimate, y = term_label)) +
  geom_vline(xintercept = 0, linetype = "dashed", linewidth = 0.8) +
  geom_point(size = 3) +
  geom_errorbarh(
    aes(xmin = conf.low, xmax = conf.high),
    height = 0.18,
    linewidth = 0.8
  ) +
  facet_wrap(~ model, scales = "free_x") +
  labs(
    title = "Regression Coefficient Plot",
    subtitle = "Two Dependent Variables",
    x = "Coefficient Estimate with 95% Confidence Interval",
    y = NULL
  ) +
  theme_minimal(base_size = 15) +
  theme(
    plot.title = element_text(size = 24, face = "bold"),
    plot.subtitle = element_text(size = 16),
    strip.text = element_text(size = 16, face = "bold"),
    axis.text.y = element_text(size = 14),
    axis.text.x = element_text(size = 12),
    panel.grid.minor = element_blank()
  )
`height` was translated to `width`.

cor(df$Democracy, df$political_stability, use = "complete.obs")
[1] -0.2777268
df %>%
  select(Democracy, political_stability, strategic_ambiguity, unga_idealpoint) %>%
  cor(use = "complete.obs")
                     Democracy political_stability strategic_ambiguity
Democracy            1.0000000         -0.30877837          0.47425882
political_stability -0.3087784          1.00000000         -0.02713794
strategic_ambiguity  0.4742588         -0.02713794          1.00000000
unga_idealpoint     -0.3313889         -0.07471228         -0.21974143
                    unga_idealpoint
Democracy               -0.33138887
political_stability     -0.07471228
strategic_ambiguity     -0.21974143
unga_idealpoint          1.00000000
ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = Democracy, y = strategic_ambiguity)) +
  geom_point(size = 2.5, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Political Openness and Strategic Ambiguity",
    x = "Political Openness Index",
    y = "Strategic Ambiguity"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = Democracy, y = unga_idealpoint)) +
  geom_point(size = 2.5, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE) +
  labs(
    title = "Political Openness and UNGA Ideal Point Distance",
    subtitle = "Lower values indicate stronger hedging",
    x = "Political Openness Index",
    y = "UNGA Ideal Point Distance"
  ) +
  theme_minimal(base_size = 14)
`geom_smooth()` using formula = 'y ~ x'

library(ggplot2)
library(dplyr)

ggplot(df %>% filter(!is.na(strategic_ambiguity)),
       aes(x = Democracy, y = strategic_ambiguity, color = Country)) +
  geom_point(size = 3, alpha = 0.75) +
  geom_smooth(
    aes(group = 1),
    method = "lm",
    se = TRUE,
    color = "black",
    linewidth = 1
  ) +
  labs(
    title = "Political Openness and Strategic Ambiguity",
    x = "Political Openness Index",
    y = "Strategic Ambiguity",
    color = "Country"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "right",
    plot.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  )
`geom_smooth()` using formula = 'y ~ x'

library(ggplot2)
library(dplyr)

ggplot(df %>% filter(!is.na(unga_idealpoint)),
       aes(x = Democracy, y = unga_idealpoint, color = Country)) +
  geom_point(size = 3, alpha = 0.75) +
  geom_smooth(
    aes(group = 1),
    method = "lm",
    se = TRUE,
    color = "black",
    linewidth = 1
  ) +
  labs(
    title = "Political Openness and UNGA Ideal Point Distance",
    subtitle = "Lower values indicate stronger hedging",
    x = "Political Openness Index",
    y = "UNGA Ideal Point Distance",
    color = "Country"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "right",
    plot.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  )
`geom_smooth()` using formula = 'y ~ x'