# Global options for R chunks

knitr::opts_chunk$set(
    echo = TRUE,
    fig.align = "center",
    fig.height = 7,
    fig.width = 10,
    message = TRUE,
    warning = TRUE
)
# Load necessary packages

# Ensure these are installed by running install.packages(c("readxl", "MASS", "dplyr", "ggplot2", "broom", "stringr", "forcats", "effects", "tidyr", "tibble", "stargazer")) in your R Console once.

library(readxl)

library(MASS)

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:MASS':
## 
##     select
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)

library(broom)

library(stringr)

library(forcats)

library(effects)
## Loading required package: carData
## lattice theme set by effectsTheme()
## See ?effectsTheme for details.
library(tidyr)

library(tibble)

library(stargazer) # Load for professional tables
## 
## Please cite as:
##  Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
##  R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
# --- Load the Data ---

# IMPORTANT: Ensure the file path is correct and the Excel file is NOT open.

df <- read_excel("C:/Users/dusti/OneDrive/Desktop/Disertation Proposal/Book, Survey, Interviews Data/Survey/Stats-Quant/RQ2ProduceOffersStats.xlsx")



# --- Print Column Names (for verification) ---

cat("### Original Column Names in DataFrame:\n")
## ### Original Column Names in DataFrame:
print(colnames(df))
##  [1] "Participant#"                        "PermanentWorkers"                   
##  [3] "ProduceOffersRecieved"               "MarketPricingImpact"                
##  [5] "GovPoliticiesImpactProd"             "VineyardFinancialStability"         
##  [7] "RemittanceIncomeTotal"               "RemittanceInvestmentAmtIntoVineyard"
##  [9] "ProduceLostPerc"                     "HealthyProduceUnsoldPerc"           
## [11] "MarketAccessRestricted"              "FearFinancialStability"
# --- Data Cleaning and Type Coercion (Revised for Separation/Sparsity) ---



# Dependent variable: ProduceOffersRecieved

produce_offers_levels <- sort(unique(df$ProduceOffersRecieved[!is.na(df$ProduceOffersRecieved)]))

df$ProduceOffersRecieved <- ordered(df$ProduceOffersRecieved, levels = produce_offers_levels)

cat("\n### Levels of ProduceOffersRecieved (after conversion to ordered factor):\n")
## 
## ### Levels of ProduceOffersRecieved (after conversion to ordered factor):
print(levels(df$ProduceOffersRecieved))
## [1] "0" "1" "2" "3" "4"
# --- RESTRUCTURE PROBLEMatic LIKERT SCALE VARIABLES TO BINARY-LIKE ---

# If value is 5 (Strongly Agree/High Impact), map to 2. Else (1,2,3,4), map to 1.

df$MarketPricingImpact_Bin <- df$MarketPricingImpact %>%

  recode(`1` = 1, `2` = 1, `3` = 1, `4` = 1, `5` = 2) %>%

  ordered(levels = c(1, 2))

cat("\n### Levels of MarketPricingImpact_Bin:\n")
## 
## ### Levels of MarketPricingImpact_Bin:
print(levels(df$MarketPricingImpact_Bin))
## [1] "1" "2"
df$GovPoliticiesImpactProd_Bin <- df$GovPoliticiesImpactProd %>%

  recode(`1` = 1, `2` = 1, `3` = 1, `4` = 1, `5` = 2) %>%

  ordered(levels = c(1, 2))

cat("\n### Levels of GovPoliticiesImpactProd_Bin:\n")
## 
## ### Levels of GovPoliticiesImpactProd_Bin:
print(levels(df$GovPoliticiesImpactProd_Bin))
## [1] "1" "2"
df$MarketAccessRestricted_Bin <- df$MarketAccessRestricted %>%

  recode(`1` = 1, `2` = 1, `3` = 1, `4` = 1, `5` = 2) %>%

  ordered(levels = c(1, 2))

cat("\n### Levels of MarketAccessRestricted_Bin:\n")
## 
## ### Levels of MarketAccessRestricted_Bin:
print(levels(df$MarketAccessRestricted_Bin))
## [1] "1" "2"
df$FearFinancialStability_Bin <- df$FearFinancialStability %>%

  recode(`1` = 1, `2` = 1, `3` = 1, `4` = 1, `5` = 2) %>%

  ordered(levels = c(1, 2))

cat("\n### Levels of FearFinancialStability_Bin:\n")
## 
## ### Levels of FearFinancialStability_Bin:
print(levels(df$FearFinancialStability_Bin))
## [1] "1" "2"
df$VineyardFinancialStability_Bin <- df$VineyardFinancialStability %>%

  recode(`1` = 1, `2` = 1, `3` = 1, `4` = 1, `5` = 2) %>%

  ordered(levels = c(1, 2))

cat("\n### Levels of VineyardFinancialStability_Bin:\n")
## 
## ### Levels of VineyardFinancialStability_Bin:
print(levels(df$VineyardFinancialStability_Bin))
## [1] "1" "2"
df$RemittanceIncome_Binned <- df$RemittanceIncomeTotal %>%

  recode(`0` = 1, `1` = 2, `2` = 3, `3` = 3) %>%

  ordered(levels = c(1, 2, 3))

cat("\n### Levels of RemittanceIncome_Binned:\n")
## 
## ### Levels of RemittanceIncome_Binned:
print(levels(df$RemittanceIncome_Binned))
## [1] "1" "2" "3"
# --- RESTRUCTURE SPARSE NUMERICAL VARIABLES BY BINNING ---

df$RemittanceInvestment_Binned <- df$RemittanceInvestmentAmtIntoVineyard %>%

  cut(breaks = c(-Inf, 0, 1000, 3000, Inf),

      labels = c("No Investment", "Low Investment", "Medium Investment", "High Investment"),

      right = TRUE, include.lowest = TRUE) %>%

  ordered(levels = c("No Investment", "Low Investment", "Medium Investment", "High Investment"))

cat("\n### Levels of RemittanceInvestment_Binned:\n")
## 
## ### Levels of RemittanceInvestment_Binned:
print(levels(df$RemittanceInvestment_Binned))
## [1] "No Investment"     "Low Investment"    "Medium Investment"
## [4] "High Investment"
df$HealthyProduceUnsold_Binned <- df$HealthyProduceUnsoldPerc %>%

  cut(breaks = c(-Inf, 0, 10, 25, Inf),

      labels = c("None", "Low (0-10%)", "Medium (10-25%)", "High (>25%)"),

      right = TRUE, include.lowest = TRUE) %>%

  ordered(levels = c("None", "Low (0-10%)", "Medium (10-25%)", "High (>25%)"))

cat("\n### Levels of HealthyProduceUnsold_Binned:\n")
## 
## ### Levels of HealthyProduceUnsold_Binned:
print(levels(df$HealthyProduceUnsold_Binned))
## [1] "None"            "Low (0-10%)"     "Medium (10-25%)" "High (>25%)"
# Numerical (ratio) variables:

df$PermanentWorkers <- as.numeric(df$PermanentWorkers)

df$ProduceLostPerc <- as.numeric(df$ProduceLostPerc)



# --- Select Relevant Columns for the Model and Handle Missing Data ---

selected_cols <- c(

    "ProduceOffersRecieved",

    "PermanentWorkers",

    "MarketPricingImpact_Bin",

    "GovPoliticiesImpactProd_Bin",

    "VineyardFinancialStability_Bin",

    "RemittanceIncome_Binned",

    "RemittanceInvestment_Binned",

    "ProduceLostPerc",

    "HealthyProduceUnsold_Binned",

    "MarketAccessRestricted_Bin",

    "FearFinancialStability_Bin"

)



model_data <- df %>%

  dplyr::select(all_of(selected_cols)) %>%

  na.omit()



cat(paste("\n### Number of observations for OLR model after selection and NA removal:", nrow(model_data), "\n"))
## 
## ### Number of observations for OLR model after selection and NA removal: 61
cat(paste("### Number of variables for OLR model:", ncol(model_data), "\n"))
## ### Number of variables for OLR model: 11
cat("\n### Column names in model_data (should show ALL _Bin and _Binned variables):\n")
## 
## ### Column names in model_data (should show ALL _Bin and _Binned variables):
print(colnames(model_data))
##  [1] "ProduceOffersRecieved"          "PermanentWorkers"              
##  [3] "MarketPricingImpact_Bin"        "GovPoliticiesImpactProd_Bin"   
##  [5] "VineyardFinancialStability_Bin" "RemittanceIncome_Binned"       
##  [7] "RemittanceInvestment_Binned"    "ProduceLostPerc"               
##  [9] "HealthyProduceUnsold_Binned"    "MarketAccessRestricted_Bin"    
## [11] "FearFinancialStability_Bin"
# --- Run the Ordinal Logistic Regression Model ---

olr_model <- polr(

  ProduceOffersRecieved ~ .,

  data = model_data,

  Hess = TRUE # Needed to calculate standard errors and p-values

)
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
# --- View Model Summary ---

summary_model <- summary(olr_model)

cat("### Model Summary:\n")
## ### Model Summary:
print(summary_model)
## Call:
## polr(formula = ProduceOffersRecieved ~ ., data = model_data, 
##     Hess = TRUE)
## 
## Coefficients:
##                                     Value Std. Error  t value
## PermanentWorkers                  0.46345    0.21631  2.14254
## MarketPricingImpact_Bin.L        -0.44050    1.54479 -0.28515
## GovPoliticiesImpactProd_Bin.L     0.81322    0.72717  1.11834
## VineyardFinancialStability_Bin.L -0.13370    0.54970 -0.24322
## RemittanceIncome_Binned.L        -0.06837    1.87891 -0.03639
## RemittanceIncome_Binned.Q         0.18385    1.09684  0.16762
## RemittanceInvestment_Binned.L     1.83100    1.97796  0.92570
## RemittanceInvestment_Binned.Q     0.12460    1.44879  0.08600
## RemittanceInvestment_Binned.C     0.40723    1.04364  0.39020
## ProduceLostPerc                   0.02750    0.01541  1.78461
## HealthyProduceUnsold_Binned.L    -1.08853    0.97265 -1.11914
## HealthyProduceUnsold_Binned.Q    -0.84048    0.90722 -0.92644
## HealthyProduceUnsold_Binned.C    -2.31922    0.89319 -2.59655
## MarketAccessRestricted_Bin.L      0.50671    0.50935  0.99482
## FearFinancialStability_Bin.L     -0.47242    0.73669 -0.64127
## 
## Intercepts:
##     Value   Std. Error t value
## 0|1 -0.1790  1.2669    -0.1413
## 1|2  3.4327  1.3487     2.5451
## 2|3  5.0580  1.4890     3.3970
## 3|4  6.5886  1.7781     3.7053
## 
## Residual Deviance: 115.855 
## AIC: 153.855
# --- Calculate p-values (polr doesn't automatically provide them) ---

coefs <- summary_model$coefficients

std_errs <- sqrt(diag(vcov(olr_model)))

coef_table <- cbind(coefs, "Std. Error" = std_errs)

p_values <- pnorm(abs(coef_table[, "t value"]), lower.tail = FALSE) * 2

coef_table <- cbind(coef_table, "p-value" = p_values)

cat("\n### Model Coefficients with p-values:\n")
## 
## ### Model Coefficients with p-values:
print(coef_table)
##                                        Value Std. Error     t value Std. Error
## PermanentWorkers                  0.46345427 0.21631060  2.14254070 0.21631060
## MarketPricingImpact_Bin.L        -0.44049716 1.54479166 -0.28514988 1.54479166
## GovPoliticiesImpactProd_Bin.L     0.81322301 0.72716653  1.11834494 0.72716653
## VineyardFinancialStability_Bin.L -0.13369728 0.54969683 -0.24322003 0.54969683
## RemittanceIncome_Binned.L        -0.06836761 1.87890737 -0.03638690 1.87890737
## RemittanceIncome_Binned.Q         0.18384944 1.09684164  0.16761712 1.09684164
## RemittanceInvestment_Binned.L     1.83100194 1.97796051  0.92570197 1.97796051
## RemittanceInvestment_Binned.Q     0.12459905 1.44878989  0.08600216 1.44878989
## RemittanceInvestment_Binned.C     0.40722879 1.04363568  0.39020206 1.04363568
## ProduceLostPerc                   0.02749973 0.01540942  1.78460505 0.01540942
## HealthyProduceUnsold_Binned.L    -1.08852774 0.97265078 -1.11913521 0.97265078
## HealthyProduceUnsold_Binned.Q    -0.84048237 0.90721676 -0.92644052 0.90721676
## HealthyProduceUnsold_Binned.C    -2.31921913 0.89319340 -2.59654755 0.89319340
## MarketAccessRestricted_Bin.L      0.50670821 0.50934696  0.99481934 0.50934696
## FearFinancialStability_Bin.L     -0.47242299 0.73669415 -0.64127426 0.73669415
## 0|1                              -0.17902091 1.26691713 -0.14130436 1.26691713
## 1|2                               3.43270286 1.34872491  2.54514678 1.34872491
## 2|3                               5.05803058 1.48896330  3.39701495 1.48896330
## 3|4                               6.58856169 1.77813160  3.70532850 1.77813160
##                                       p-value
## PermanentWorkers                 0.0321499972
## MarketPricingImpact_Bin.L        0.7755293135
## GovPoliticiesImpactProd_Bin.L    0.2634197005
## VineyardFinancialStability_Bin.L 0.8078349482
## RemittanceIncome_Binned.L        0.9709738606
## RemittanceIncome_Binned.Q        0.8668845014
## RemittanceInvestment_Binned.L    0.3546008828
## RemittanceInvestment_Binned.Q    0.9314647028
## RemittanceInvestment_Binned.C    0.6963871395
## ProduceLostPerc                  0.0743254018
## HealthyProduceUnsold_Binned.L    0.2630824592
## HealthyProduceUnsold_Binned.Q    0.3542170943
## HealthyProduceUnsold_Binned.C    0.0094165871
## MarketAccessRestricted_Bin.L     0.3198241378
## FearFinancialStability_Bin.L     0.5213445125
## 0|1                              0.8876295069
## 1|2                              0.0109231811
## 2|3                              0.0006812525
## 3|4                              0.0002111169
# --- Calculate Odds Ratios ---

cat("\n### Odds Ratios:\n")
## 
## ### Odds Ratios:
print(exp(coef(olr_model)))
##                 PermanentWorkers        MarketPricingImpact_Bin.L 
##                       1.58955526                       0.64371631 
##    GovPoliticiesImpactProd_Bin.L VineyardFinancialStability_Bin.L 
##                       2.25516471                       0.87485486 
##        RemittanceIncome_Binned.L        RemittanceIncome_Binned.Q 
##                       0.93391709                       1.20183486 
##    RemittanceInvestment_Binned.L    RemittanceInvestment_Binned.Q 
##                       6.24013580                       1.13269421 
##    RemittanceInvestment_Binned.C                  ProduceLostPerc 
##                       1.50264786                       1.02788134 
##    HealthyProduceUnsold_Binned.L    HealthyProduceUnsold_Binned.Q 
##                       0.33671186                       0.43150233 
##    HealthyProduceUnsold_Binned.C     MarketAccessRestricted_Bin.L 
##                       0.09835035                       1.65981842 
##     FearFinancialStability_Bin.L 
##                       0.62348973
# Prepare data for stargazer (ensure correct variable names for labels)

stargazer(olr_model, type = "html",

          title = "Ordinal Logistic Regression Results: Produce Offers Received",

          dep.var.labels = "Produce Offers Received (Higher = More Offers)",

          covariate.labels = c(

            "Permanent Workers",

            "Market Pricing Impact (Strong Agree)",

            "Gov Policies Impact (Strong Agree)",

            "Vineyard Financial Stability (Strong Agree)",

            "Remittance Income: Low",

            "Remittance Income: Med/High",

            "Remittance Investment: Low",

            "Remittance Investment: Medium",

            "Remittance Investment: High",

            "Produce Lost (%)",

            "Healthy Produce Unsold: Low",

            "Healthy Produce Unsold: Medium",

            "Healthy Produce Unsold: High",

            "Market Access Restricted (Strong Agree)",

            "Fear Financial Stability (Strong Agree)"

          ),

          ci = TRUE, ci.level = 0.90, # Display 90% CIs

          notes = "Odds Ratios (exp(Coef)) are interpreted as the change in odds of receiving more produce offers for a one-unit increase in the predictor. Significance at p < 0.10.",

          notes.align = "l"

)
## 
## <table style="text-align:center"><caption><strong>Ordinal Logistic Regression Results: Produce Offers Received</strong></caption>
## <tr><td colspan="2" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left"></td><td><em>Dependent variable:</em></td></tr>
## <tr><td></td><td colspan="1" style="border-bottom: 1px solid black"></td></tr>
## <tr><td style="text-align:left"></td><td>Produce Offers Received (Higher = More Offers)</td></tr>
## <tr><td colspan="2" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left">Permanent Workers</td><td>0.463<sup>**</sup></td></tr>
## <tr><td style="text-align:left"></td><td>(0.108, 0.819)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Market Pricing Impact (Strong Agree)</td><td>-0.440</td></tr>
## <tr><td style="text-align:left"></td><td>(-2.981, 2.100)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Gov Policies Impact (Strong Agree)</td><td>0.813</td></tr>
## <tr><td style="text-align:left"></td><td>(-0.383, 2.009)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Vineyard Financial Stability (Strong Agree)</td><td>-0.134</td></tr>
## <tr><td style="text-align:left"></td><td>(-1.038, 0.770)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Remittance Income: Low</td><td>-0.068</td></tr>
## <tr><td style="text-align:left"></td><td>(-3.159, 3.022)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Remittance Income: Med/High</td><td>0.184</td></tr>
## <tr><td style="text-align:left"></td><td>(-1.620, 1.988)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Remittance Investment: Low</td><td>1.831</td></tr>
## <tr><td style="text-align:left"></td><td>(-1.422, 5.084)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Remittance Investment: Medium</td><td>0.125</td></tr>
## <tr><td style="text-align:left"></td><td>(-2.258, 2.508)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Remittance Investment: High</td><td>0.407</td></tr>
## <tr><td style="text-align:left"></td><td>(-1.309, 2.124)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Produce Lost (%)</td><td>0.027<sup>*</sup></td></tr>
## <tr><td style="text-align:left"></td><td>(0.002, 0.053)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Healthy Produce Unsold: Low</td><td>-1.089</td></tr>
## <tr><td style="text-align:left"></td><td>(-2.688, 0.511)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Healthy Produce Unsold: Medium</td><td>-0.840</td></tr>
## <tr><td style="text-align:left"></td><td>(-2.333, 0.652)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Healthy Produce Unsold: High</td><td>-2.319<sup>***</sup></td></tr>
## <tr><td style="text-align:left"></td><td>(-3.788, -0.850)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Market Access Restricted (Strong Agree)</td><td>0.507</td></tr>
## <tr><td style="text-align:left"></td><td>(-0.331, 1.345)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td style="text-align:left">Fear Financial Stability (Strong Agree)</td><td>-0.472</td></tr>
## <tr><td style="text-align:left"></td><td>(-1.684, 0.739)</td></tr>
## <tr><td style="text-align:left"></td><td></td></tr>
## <tr><td colspan="2" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left">Observations</td><td>61</td></tr>
## <tr><td colspan="2" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left"><em>Note:</em></td><td style="text-align:left"><sup>*</sup>p<0.1; <sup>**</sup>p<0.05; <sup>***</sup>p<0.01</td></tr>
## <tr><td style="text-align:left"></td><td style="text-align:left">Odds Ratios (exp(Coef)) are interpreted as the change in odds of receiving more produce offers for a one-unit increase in the predictor. Significance at p < 0.10.</td></tr>
## </table>
# --- Code for Forest Plot ---

# Prepare Data for Forest Plot

odds_ratios <- exp(coef(olr_model))

conf_intervals <- confint(olr_model, level = 0.90) # Using 90% Confidence Intervals
## Waiting for profiling to be done...
odds_ratios_ci <- exp(conf_intervals)



forest_data <- data.frame(

  term = names(odds_ratios),

  odds_ratio = odds_ratios,

  lower_ci = odds_ratios_ci[, 1],

  upper_ci = odds_ratios_ci[, 2]

)



if (exists("coef_table")) {

  forest_data <- forest_data %>%

    filter(!str_detect(term, "\\|")) # Remove intercept terms first



  p_value_lookup <- setNames(coef_table[forest_data$term, "p-value"], forest_data$term)

  forest_data$`p-value` <- p_value_lookup[forest_data$term]



  forest_data$sig <- ifelse(forest_data$`p-value` < 0.10, "Significant (p < 0.10)", "Not Significant") # Significance at p < 0.10

} else {

  warning("coef_table not found. P-values missing for significance indication in plot.")

  forest_data$sig <- "Unknown Significance"

}



forest_data <- forest_data %>%

  mutate(

    term = case_when(

      term == "MarketPricingImpact_Bin2" ~ "Market Pricing Impact (Strong Agree)",

      term == "GovPoliticiesImpactProd_Bin2" ~ "Gov Policies Impact (Strong Agree)",

      term == "VineyardFinancialStability_Bin2" ~ "Vineyard Financial Stability (Strong Agree)",

      term == "RemittanceIncome_Binned2" ~ "Remittance Income: Low",

      term == "RemittanceIncome_Binned3" ~ "Remittance Income: Med/High",

      term == "RemittanceInvestment_BinnedLow Investment" ~ "Remittance Investment: Low",

      term == "RemittanceInvestment_BinnedMedium Investment" ~ "Remittance Investment: Medium",

      term == "RemittanceInvestment_BinnedHigh Investment" ~ "Remittance Investment: High",

      term == "HealthyProduceUnsold_BinnedLow (0-10%)" ~ "Healthy Produce Unsold: Low",

      term == "HealthyProduceUnsold_BinnedMedium (10-25%)" ~ "Healthy Produce Unsold: Medium",

      term == "HealthyProduceUnsold_BinnedHigh (>25%)" ~ "Healthy Produce Unsold: High",

      term == "MarketAccessRestricted_Bin2" ~ "Market Access Restricted (Strong Agree)",

      term == "FearFinancialStability_Bin2" ~ "Fear Financial Stability (Strong Agree)",

      TRUE ~ term

    ),

    term = fct_inorder(term)

  ) %>%

  arrange(desc(odds_ratio))



max_finite_upper_ci <- max(forest_data$upper_ci[!is.infinite(forest_data$upper_ci)], na.rm = TRUE)

max_x_limit <- ifelse(is.finite(max_finite_upper_ci), max_finite_upper_ci * 1.5, 1000)



forest_data$lower_ci[is.infinite(forest_data$lower_ci)] <- 0.001

forest_data$upper_ci[is.infinite(forest_data$upper_ci)] <- max_x_limit



forest_plot <- ggplot(forest_data, aes(y = term, x = odds_ratio, xmin = lower_ci, xmax = upper_ci, color = sig)) +

  geom_point(size = 3) +

  geom_errorbarh(height = 0.2) +

  geom_vline(xintercept = 1, linetype = "dashed", color = "black") +

  scale_x_log10(limits = c(min(forest_data$lower_ci, na.rm=TRUE), max_x_limit)) +

  labs(

    title = "Odds Ratios with 90% Confidence Intervals (Final Transformed Model)",

    x = "Odds Ratio (Log Scale)",

    y = "Predictor Variable",

    color = "Significance"

  ) +

  theme_minimal() +

  theme(

    plot.title = element_text(hjust = 0.5, face = "bold"),

    axis.text.y = element_text(size = 10, face = "bold"),

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

    axis.title.y = element_text(size = 12),

    legend.position = "bottom"

  ) +

  scale_color_manual(values = c("Significant (p < 0.10)" = "darkgreen", "Not Significant" = "darkred", "Unknown Significance" = "gray"))



print(forest_plot)

ggsave("olr_forest_plot_final_transformed_90CI.png", plot = forest_plot, width = 10, height = 8, dpi = 300)

# Example 1: MarketPricingImpact_Bin

effect_mp_impact_bin <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_mp_bin <- as.data.frame(effect_mp_impact_bin$`MarketPricingImpact_Bin`)

predicted_probs_long_mp_bin <- predicted_probs_mp_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_mp_bin <- ggplot(predicted_probs_long_mp_bin, aes(x = MarketPricingImpact_Bin, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Market Pricing Impact (Binned)", x = "Market Pricing Impact (1=Less than Strong Agree, 2=Strong Agree)", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete(labels = c("Less than Strong Agree", "Strong Agree")) + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_mp_bin)

ggsave("olr_predicted_probs_market_pricing_binned_90CI.png", plot = probs_plot_mp_bin, width = 10, height = 6, dpi = 300)





# Example 2: GovPoliticiesImpactProd_Bin

effect_gp_impact_bin <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_gp_bin <- as.data.frame(effect_gp_impact_bin$`GovPoliticiesImpactProd_Bin`)

predicted_probs_long_gp_bin <- predicted_probs_gp_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_gp_bin <- ggplot(predicted_probs_long_gp_bin, aes(x = GovPoliticiesImpactProd_Bin, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Gov Policies Impact (Binned)", x = "Gov Policies Impact (1=Less than Strong Agree, 2=Strong Agree)", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete(labels = c("Less than Strong Agree", "Strong Agree")) + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_gp_bin)

ggsave("olr_predicted_probs_gov_policies_binned_90CI.png", plot = probs_plot_gp_bin, width = 10, height = 6, dpi = 300)





# Example 3: VineyardFinancialStability_Bin

effect_vfs_bin <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_vfs_bin <- as.data.frame(effect_vfs_bin$`VineyardFinancialStability_Bin`)

predicted_probs_long_vfs_bin <- predicted_probs_vfs_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_vfs_bin <- ggplot(predicted_probs_long_vfs_bin, aes(x = VineyardFinancialStability_Bin, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Vineyard Financial Stability (Binned)", x = "Financial Stability (1=Less than Strong Agree, 2=Strong Agree)", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete(labels = c("Less than Strong Agree", "Strong Agree")) + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_vfs_bin)

ggsave("olr_predicted_probs_vineyard_stability_binned_90CI.png", plot = probs_plot_vfs_bin, width = 10, height = 6, dpi = 300)





# Example 4: RemittanceIncome_Binned

effect_rib <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_rib <- as.data.frame(effect_rib$`RemittanceIncome_Binned`)

predicted_probs_long_rib <- predicted_probs_rib %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_rib <- ggplot(predicted_probs_long_rib, aes(x = RemittanceIncome_Binned, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Remittance Income (Binned)", x = "Remittance Income", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete() + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_rib)

ggsave("olr_predicted_probs_remittance_income_binned_90CI.png", plot = probs_plot_rib, width = 10, height = 6, dpi = 300)





# Example 5: RemittanceInvestment_Binned

effect_riib <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_riib <- as.data.frame(effect_riib$`RemittanceInvestment_Binned`)

predicted_probs_long_riib <- predicted_probs_riib %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_riib <- ggplot(predicted_probs_long_riib, aes(x = RemittanceInvestment_Binned, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Remittance Investment (Binned)", x = "Remittance Investment", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete() + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_riib)

ggsave("olr_predicted_probs_remittance_investment_binned_90CI.png", plot = probs_plot_riib, width = 10, height = 6, dpi = 300)





# Example 6: HealthyProduceUnsold_Binned

effect_hpu_binned <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_hpu_bin <- as.data.frame(effect_hpu_binned$`HealthyProduceUnsold_Binned`)

predicted_probs_long_hpu_bin <- predicted_probs_hpu_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_hpu_bin <- ggplot(predicted_probs_long_hpu_bin, aes(x = HealthyProduceUnsold_Binned, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Healthy Produce Unsold (Binned)", x = "Healthy Produce Unsold", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete() + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_hpu_bin)

ggsave("olr_predicted_probs_healthy_unsold_binned_90CI.png", plot = probs_plot_hpu_bin, width = 10, height = 6, dpi = 300)





# Example 7: MarketAccessRestricted_Bin

effect_ma_restricted_bin <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_ma_bin <- as.data.frame(effect_ma_restricted_bin$`MarketAccessRestricted_Bin`)

predicted_probs_long_ma_bin <- predicted_probs_ma_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_ma_bin <- ggplot(predicted_probs_long_ma_bin, aes(x = MarketAccessRestricted_Bin, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Market Access Restriction (Binned)", x = "Market Access Restriction (1=Less than Strong Agree, 2=Strong Agree)", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete(labels = c("Less than Strong Agree", "Strong Agree")) + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_ma_bin)

ggsave("olr_predicted_probs_market_access_binned_90CI.png", plot = probs_plot_ma_bin, width = 10, height = 6, dpi = 300)





# Example 8: FearFinancialStability_Bin

effect_ffs_bin <- effects::allEffects(olr_model, latent = FALSE)

predicted_probs_ffs_bin <- as.data.frame(effect_ffs_bin$`FearFinancialStability_Bin`)

predicted_probs_long_ffs_bin <- predicted_probs_ffs_bin %>%

  pivot_longer(cols = starts_with("prob."), names_to = "ProduceOffersRecieved_Category", values_to = "Predicted_Probability") %>%

  mutate(ProduceOffersRecieved_Category = str_replace(ProduceOffersRecieved_Category, "prob.", "Offers = ") %>% fct_inorder())



probs_plot_ffs_bin <- ggplot(predicted_probs_long_ffs_bin, aes(x = FearFinancialStability_Bin, y = Predicted_Probability, color = ProduceOffersRecieved_Category, group = ProduceOffersRecieved_Category)) +

  geom_line(linewidth = 1.2) + geom_point(size = 3) +

  labs(title = "Predicted Probability of Produce Offers by Fear Financial Stability (Binned)", x = "Fear Financial Stability (1=Less than Strong Agree, 2=Strong Agree)", y = "Predicted Probability", color = "Produce Offers Received") +

  scale_y_continuous(labels = scales::percent, limits = c(0, 1)) + scale_x_discrete(labels = c("Less than Strong Agree", "Strong Agree")) + theme_minimal() +

  theme(plot.title = element_text(hjust = 0.5, face = "bold"), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12), legend.position = "bottom")

print(probs_plot_ffs_bin)

ggsave("olr_predicted_probs_fear_financial_stability_binned_90CI.png", plot = probs_plot_ffs_bin, width = 10, height = 6, dpi = 300)



# --- Final Check: Session Information (Useful for debugging environment issues) ---

sessionInfo()
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26100)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=English_United States.utf8 
## [2] LC_CTYPE=English_United States.utf8   
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.utf8    
## 
## time zone: America/Chicago
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] stargazer_5.2.3 tibble_3.3.0    tidyr_1.3.1     effects_4.2-2  
##  [5] carData_3.0-5   forcats_1.0.0   stringr_1.5.1   broom_1.0.8    
##  [9] ggplot2_3.5.2   dplyr_1.1.4     MASS_7.3-65     readxl_1.4.5   
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.10        generics_0.1.4     stringi_1.8.7      lattice_0.22-7    
##  [5] lme4_1.1-37        digest_0.6.37      magrittr_2.0.3     evaluate_1.0.4    
##  [9] grid_4.5.1         RColorBrewer_1.1-3 fastmap_1.2.0      cellranger_1.1.0  
## [13] jsonlite_2.0.0     Matrix_1.7-3       nnet_7.3-20        backports_1.5.0   
## [17] DBI_1.2.3          survival_3.8-3     purrr_1.1.0        scales_1.4.0      
## [21] textshaping_1.0.1  jquerylib_0.1.4    Rdpack_2.6.4       reformulas_0.4.1  
## [25] cli_3.6.5          mitools_2.4        rlang_1.1.6        rbibutils_2.3     
## [29] splines_4.5.1      withr_3.0.2        cachem_1.1.0       yaml_2.3.10       
## [33] tools_4.5.1        nloptr_2.2.1       minqa_1.2.8        colorspace_2.1-1  
## [37] boot_1.3-31        vctrs_0.6.5        R6_2.6.1           lifecycle_1.0.4   
## [41] ragg_1.4.0         insight_1.3.1      pkgconfig_2.0.3    pillar_1.11.0     
## [45] bslib_0.9.0        gtable_0.3.6       glue_1.8.0         Rcpp_1.1.0        
## [49] systemfonts_1.2.3  xfun_0.52          tidyselect_1.2.1   rstudioapi_0.17.1 
## [53] knitr_1.50         farver_2.1.2       survey_4.4-2       htmltools_0.5.8.1 
## [57] nlme_3.1-168       labeling_0.4.3     rmarkdown_2.29     compiler_4.5.1