Load data

data <- read_excel("fiscal_study.xlsx")

Calculate the percentage of missing values in each column

missing_percentage <- colMeans(is.na(data)) * 100
missing_percentage  # Display the results
##   country      code    region    income      year   che_usd       fby      ggdy 
##  0.000000  0.000000  0.000000  0.000000  0.000000  2.173913  2.173913  0.000000 
##       pby       cby   fxsovsh   secnres   avglife   xtdebty   prdebty stdebtall 
##  2.173913  2.173913 91.739130 53.478261 61.304348  3.478261  3.478261  3.478261 
##   sovrate       hc5 
##  5.217391 78.260870

Rename “upper-middle” and “lower-middle” groups in the “income” column as “low”

data$income[data$income %in% c("Upper-middle", "Lower-middle")] <- "low"

Replace NA values with the mean of each column

clean_data <- data %>%
  mutate(across(everything(), ~replace_na(., mean(., na.rm = TRUE))))
## Warning: There were 4 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `across(everything(), ~replace_na(., mean(., na.rm = TRUE)))`.
## Caused by warning in `mean.default()`:
## ! argument is not numeric or logical: returning NA
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 3 remaining warnings.
head(clean_data)  # Display the first few rows of the filled data frame
## # A tibble: 6 × 18
##   country code  region income  year che_usd     fby  ggdy    pby     cby fxsovsh
##   <chr>   <chr> <chr>  <chr>  <dbl>   <dbl>   <dbl> <dbl>  <dbl>   <dbl>   <dbl>
## 1 Armenia ARM   EUR    low     2000    80.2  0.0127  39.6  0.979 -0.0834    56.8
## 2 Armenia ARM   EUR    low     2001    98.4  0.0127  38.1  0.979 -0.0834    56.8
## 3 Armenia ARM   EUR    low     2002   181.   0.0127  38.2  0.979 -0.0834    56.8
## 4 Armenia ARM   EUR    low     2003   202.   0.0127  33.0  0.979 -0.0834    56.8
## 5 Armenia ARM   EUR    low     2004   217.   0.0127  26.4  0.979 -0.0834    56.8
## 6 Armenia ARM   EUR    low     2005   287.  -1.98    20.5 -1.52  -2.94      56.8
## # ℹ 7 more variables: secnres <dbl>, avglife <dbl>, xtdebty <dbl>,
## #   prdebty <dbl>, stdebtall <dbl>, sovrate <dbl>, hc5 <dbl>
summary(data)
##    country              code              region             income         
##  Length:230         Length:230         Length:230         Length:230        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##       year         che_usd              fby                 ggdy        
##  Min.   :2000   Min.   :   80.21   Min.   :-15.74600   Min.   :  3.765  
##  1st Qu.:2005   1st Qu.: 1326.83   1st Qu.: -2.44600   1st Qu.: 26.643  
##  Median :2011   Median : 3748.74   Median : -0.68500   Median : 39.644  
##  Mean   :2011   Mean   :16954.33   Mean   :  0.01273   Mean   : 40.680  
##  3rd Qu.:2017   3rd Qu.:33609.18   3rd Qu.:  1.34100   3rd Qu.: 49.448  
##  Max.   :2022   Max.   :94484.16   Max.   : 25.34500   Max.   :138.176  
##                 NA's   :5          NA's   :5                            
##       pby               cby               fxsovsh           secnres      
##  Min.   :-13.462   Min.   :-15.82933   Min.   : 0.2103   Min.   : 0.000  
##  1st Qu.: -1.057   1st Qu.: -2.80046   1st Qu.:36.8193   1st Qu.: 1.071  
##  Median :  0.415   Median : -0.68256   Median :76.0697   Median : 2.484  
##  Mean   :  0.979   Mean   : -0.08335   Mean   :56.7833   Mean   : 5.055  
##  3rd Qu.:  2.448   3rd Qu.:  1.43299   3rd Qu.:78.0466   3rd Qu.: 4.976  
##  Max.   : 23.879   Max.   : 25.00061   Max.   :78.9923   Max.   :85.312  
##  NA's   :5         NA's   :5           NA's   :211       NA's   :123     
##     avglife           xtdebty           prdebty           stdebtall     
##  Min.   : 0.4384   Min.   :  28.56   Min.   :   1.186   Min.   : 1.629  
##  1st Qu.: 5.0082   1st Qu.:  71.56   1st Qu.:  27.793   1st Qu.:16.864  
##  Median : 6.9370   Median : 102.01   Median :  74.039   Median :28.935  
##  Mean   : 7.1780   Mean   : 556.72   Mean   : 521.605   Mean   :30.796  
##  3rd Qu.: 8.4822   3rd Qu.: 190.59   3rd Qu.: 171.259   3rd Qu.:42.768  
##  Max.   :14.1671   Max.   :6596.14   Max.   :6385.398   Max.   :74.872  
##  NA's   :141       NA's   :8         NA's   :8          NA's   :8       
##     sovrate            hc5          
##  Min.   : 2.573   Min.   :   304.5  
##  1st Qu.: 9.000   1st Qu.:   614.3  
##  Median :17.333   Median : 23738.5  
##  Mean   :15.243   Mean   : 43216.4  
##  3rd Qu.:21.000   3rd Qu.: 38284.5  
##  Max.   :21.000   Max.   :286724.3  
##  NA's   :12       NA's   :180

Plot the sum of the ‘fby’ column by the ‘income’ column

ggplot(data, aes(x = income, y = fby)) +
  geom_bar(stat = "summary", fun = "sum", fill = "skyblue", alpha = 0.8) +
  labs(x = "Income", y = "Sum of FBY", title = "Sum of FBY by Income") +
  theme_minimal()
## Warning: Removed 5 rows containing non-finite values (`stat_summary()`).

Filter data for low and high income

low_income_data <- clean_data[clean_data$income == "low", ]
high_income_data <- clean_data[clean_data$income == "High", ]

Plot time series chart for FBY for low income

low_income_plot <- low_income_data %>%
  group_by(country) %>%
  ggplot(aes(x = year, y = fby, group = country, color = country)) +
  geom_line() +
  labs(x = "Year", y = "Financial Balance Year (FBY)", title = "Time Series of FBY by Country") +
  theme_minimal()

print(low_income_plot)

Plot time series chart for FBY for high income

high_income_plot <- high_income_data %>%
  group_by(country) %>%
  ggplot(aes(x = year, y = fby, group = country, color = country)) +
  geom_line() +
  labs(x = "Year", y = "Financial Balance Year (FBY)", title = "Time Series of FBY by Country") +
  theme_minimal()

print(high_income_plot)

Calculate the mean of the ‘fby’ column by the ‘income’ column

mean_fby_by_income <- data %>%
  group_by(income) %>%
  summarise(mean_fby = mean(fby, na.rm = TRUE))
print(mean_fby_by_income)  # Print the result
## # A tibble: 2 × 2
##   income mean_fby
##   <chr>     <dbl>
## 1 High       1.97
## 2 low       -3.09

Specify the variables you want to analyze

variables_of_interest <- c("fby", "ggdy", "pby", "cby", "fxsovsh", "secnres", 
                           "avglife", "xtdebty", "prdebty", "stdebtall", "sovrate", "hc5")

Calculate correlation matrix

correlation_matrix <- cor(clean_data[variables_of_interest], use = "complete.obs")
print(correlation_matrix)
##                   fby        ggdy          pby         cby     fxsovsh
## fby        1.00000000 -0.22667594  0.898596957  0.95103308 -0.06811269
## ggdy      -0.22667594  1.00000000 -0.051125614 -0.16862720 -0.01539484
## pby        0.89859696 -0.05112561  1.000000000  0.85790262 -0.05342688
## cby        0.95103308 -0.16862720  0.857902616  1.00000000 -0.07939958
## fxsovsh   -0.06811269 -0.01539484 -0.053426878 -0.07939958  1.00000000
## secnres    0.07383923 -0.15028168  0.047640536  0.05840771  0.00000000
## avglife   -0.03616099  0.07464118 -0.008970117 -0.06012071 -0.25692508
## xtdebty    0.07193537 -0.22418301 -0.018411166  0.10025210 -0.01787830
## prdebty    0.07609003 -0.22936977 -0.016003353  0.10363650 -0.02162829
## stdebtall  0.24834003 -0.08169880  0.123142819  0.27435732 -0.29136996
## sovrate    0.55752998 -0.19725952  0.361240629  0.58331100 -0.26467288
## hc5       -0.11574335  0.18302555 -0.062290277 -0.13804413  0.04985923
##               secnres      avglife      xtdebty      prdebty   stdebtall
## fby        0.07383923 -0.036160995  0.071935371  0.076090028  0.24834003
## ggdy      -0.15028168  0.074641178 -0.224183006 -0.229369769 -0.08169880
## pby        0.04764054 -0.008970117 -0.018411166 -0.016003353  0.12314282
## cby        0.05840771 -0.060120711  0.100252098  0.103636495  0.27435732
## fxsovsh    0.00000000 -0.256925084 -0.017878299 -0.021628288 -0.29136996
## secnres    1.00000000 -0.015445123  0.135242472  0.139415337  0.06183169
## avglife   -0.01544512  1.000000000 -0.006070616 -0.003378436  0.09089401
## xtdebty    0.13524247 -0.006070616  1.000000000  0.999735531  0.11864486
## prdebty    0.13941534 -0.003378436  0.999735531  1.000000000  0.13023483
## stdebtall  0.06183169  0.090894008  0.118644859  0.130234828  1.00000000
## sovrate    0.08737562  0.111348160  0.345626862  0.354687691  0.59657340
## hc5        0.01889672 -0.040703795 -0.171524600 -0.172727376 -0.16476650
##               sovrate         hc5
## fby        0.55752998 -0.11574335
## ggdy      -0.19725952  0.18302555
## pby        0.36124063 -0.06229028
## cby        0.58331100 -0.13804413
## fxsovsh   -0.26467288  0.04985923
## secnres    0.08737562  0.01889672
## avglife    0.11134816 -0.04070380
## xtdebty    0.34562686 -0.17152460
## prdebty    0.35468769 -0.17272738
## stdebtall  0.59657340 -0.16476650
## sovrate    1.00000000 -0.26217145
## hc5       -0.26217145  1.00000000

Plot correlation matrix heatmap

heatmap(correlation_matrix, 
        col = colorRampPalette(c("blue", "white", "red"))(20),
        symm = TRUE, margins = c(3,3))

Autocorrelation analysis for FBY

# Autocorrelation analysis for FBY
# Specify the maximum lag for autocorrelation
max_lag <- 12

# Loop through each country and compute autocorrelation
for (cntry in unique(clean_data$country)) {
  # Subset data for the current country
  country_data <- clean_data[clean_data$country == cntry, ]
  
  # Compute autocorrelation for FBY
  acf_result <- acf(country_data$fby, lag.max = max_lag, plot = TRUE,
                    main = paste("Autocorrelation for", cntry),
                    xlab = "Lag", ylab = "Autocorrelation")
}

Perform t-test

t_test_result <- t.test(clean_data$fby ~ clean_data$income)
print(t_test_result)
## 
##  Welch Two Sample t-test
## 
## data:  clean_data$fby by clean_data$income
## t = 8.6696, df = 219.62, p-value = 9.658e-16
## alternative hypothesis: true difference in means between group High and group low is not equal to 0
## 95 percent confidence interval:
##  3.772699 5.992606
## sample estimates:
## mean in group High  mean in group low 
##           1.965790          -2.916863

Define the formula for regression

formula <- "fby ~ ggdy + pby + cby + fxsovsh + secnres + avglife + xtdebty + prdebty + stdebtall + sovrate + hc5"

Perform multiple regression analysis for high income

plm_high <- plm(formula, data = high_income_data, index = c("country", "year"), model = "pooling")

# Summarize the regression results for high income
summary(plm_high)
## Pooling Model
## 
## Call:
## plm(formula = formula, data = high_income_data, model = "pooling", 
##     index = c("country", "year"))
## 
## Balanced Panel: n = 6, T = 23, N = 138
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -1.317508 -0.359023 -0.065663  0.227344  4.454402 
## 
## Coefficients:
##                Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept) -6.4650e-01  9.3424e-01 -0.6920  0.490205    
## ggdy        -1.2845e-02  2.7942e-03 -4.5969 1.028e-05 ***
## pby          6.4743e-01  4.9534e-02 13.0705 < 2.2e-16 ***
## cby          4.1716e-01  4.6228e-02  9.0240 2.564e-15 ***
## fxsovsh     -1.9309e-03  6.9490e-03 -0.2779  0.781570    
## secnres      9.9853e-03  7.6083e-03  1.3124  0.191764    
## avglife     -7.4539e-02  3.6446e-02 -2.0452  0.042918 *  
## xtdebty     -2.2098e-03  2.3855e-03 -0.9264  0.356031    
## prdebty      2.1925e-03  2.4302e-03  0.9022  0.368678    
## stdebtall   -6.8492e-03  4.6852e-03 -1.4619  0.146264    
## sovrate      9.7633e-02  3.2448e-02  3.0089  0.003167 ** 
## hc5          2.0313e-06  5.9801e-06  0.3397  0.734667    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    4176.9
## Residual Sum of Squares: 67.909
## R-Squared:      0.98374
## Adj. R-Squared: 0.98232
## F-statistic: 693.082 on 11 and 126 DF, p-value: < 2.22e-16

Perform multiple regression analysis for low income

plm_low <- plm(formula, data = low_income_data, index = c("country", "year"), model = "pooling", na.action = na.exclude)
## Warning in pdata.frame(data, index): duplicate couples (id-time) in resulting pdata.frame
##  to find out which, use, e.g., table(index(your_pdataframe), useNA = "ifany")
# Summarize the regression results for low income
summary(plm_low)
## Pooling Model
## 
## Call:
## plm(formula = formula, data = low_income_data, na.action = na.exclude, 
##     model = "pooling", index = c("country", "year"))
## 
## Unbalanced Panel: n = 4, T = 23-23, N = 92
## 
## Residuals:
##      Min.   1st Qu.    Median   3rd Qu.      Max. 
## -4.459685 -0.373622  0.038982  0.465127  3.767075 
## 
## Coefficients:
##                Estimate  Std. Error t-value  Pr(>|t|)    
## (Intercept)  5.4442e+00  2.2987e+00  2.3684  0.020279 *  
## ggdy        -1.3569e-01  1.7173e-02 -7.9013 1.262e-11 ***
## pby          6.0262e-01  6.3668e-02  9.4650 1.074e-14 ***
## cby          4.3691e-01  7.0635e-02  6.1855 2.476e-08 ***
## fxsovsh     -3.9739e-02  3.0687e-02 -1.2950  0.199058    
## secnres     -2.6975e-01  1.1812e-01 -2.2837  0.025044 *  
## avglife     -1.0414e-01  1.6897e-01 -0.6163  0.539427    
## xtdebty      5.1200e-02  1.8620e-02  2.7497  0.007372 ** 
## prdebty     -1.9479e-02  2.5465e-02 -0.7649  0.446570    
## stdebtall   -4.6285e-02  2.1381e-02 -2.1648  0.033385 *  
## sovrate      7.3720e-02  6.6784e-02  1.1039  0.272964    
## hc5          7.8114e-06  3.4429e-06  2.2688  0.025972 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Total Sum of Squares:    805.87
## Residual Sum of Squares: 122.75
## R-Squared:      0.84767
## Adj. R-Squared: 0.82673
## F-statistic: 40.4717 on 11 and 80 DF, p-value: < 2.22e-16