# =============================================
# 1. Setup and Data Loading
# =============================================
# install.packages(c("tidytext", "dplyr", "tidyr", "stringr", "readr"))
library(tidytext)
library(dplyr)
library(tidyr)
library(stringr)
library(readr)
library(tibble)
library(scales)
library(tidyverse)
library(textclean)

# Load ESG disclosures
list.files("/Users/leadufrane/Desktop/Master thesis/ESGDisclosures", pattern = "\\.txt$")
filenames <- list.files(path = "/Users/leadufrane/Desktop/Master thesis/ESGDisclosures", pattern = "txt", full.names = TRUE)
files <- lapply(filenames, readLines)
texts_df <- tibble(
  Our_Filenames = sub("\\.pdf\\.txt$", "", basename(filenames)),
  text = vapply(files, paste, collapse = " ", FUN.VALUE = character(1))
)
# Load metadata
setwd("/Users/leadufrane")
metadata <- read_csv("ESGdata_export.csv")

# =============================================
# 2. Text Cleaning and Tokenization
# =============================================

texts_df <- texts_df %>%
  mutate(text = text %>%
           tolower() %>%                                         # Lowercase
           str_replace_all("(\\d)([a-zA-Z])", "\\1 \\2") %>%     # Space between numbers and letters
           str_replace_all("[^\\w\\s%/.]", " ") %>%              # Keep %, /, .
           str_replace_all("\\s+", " ") %>%                      # Remove excess whitespace
           str_trim() %>%                                        # Trim edges
           replace_white()
  )

# =============================================
# 3. Sentiment Analysis
# =============================================
# Load Loughran & McDonald sentiment lexicon and extend with ESG-specific terms
library(textdata)
lexicon_loughran <- tidytext::get_sentiments("loughran") %>%
  filter(sentiment %in% c("positive", "negative"))

# Define some additional ESG-specific positive/negative terms (if not already in lexicon)
# === POSITIVE (real or exaggerated ESG claims) ===
extra_positive <- c("sustainable", "sustainability", "renewable", "carbon-neutral", "net-zero",
                    "decarbonized", "ethical", "responsible", "transparent", "accountable",
                    "diversity", "inclusion", "inclusive", "fairtrade", "biodiversity", "green",
                    "eco-friendly", "clean", "circular", "low-carbon", "resilient", "climate-positive",
                    "zero-emission", "carbon-free", "future-proof", "impactful", "leadership", "transformative",
                    "unprecedented", "supreme", "pioneering", "groundbreaking", "exceptional", "world-class",
                    "revolutionary", "best-in-class", "extraordinary", "extreme", "ultimate", "premier")

# === NEGATIVE (greenwashing signals / environmental harm) ===
extra_negative <- c("scandal", "accident", "non-compliance","greenwashing", "greenwash", "cherry-picking", "exaggerated", "non-specific",
                    "vague", "misleading", "deceptive", "overstated", "superficial", "empty", "unverifiable",
                    "pollution", "polluting", "deforestation", "toxic", "unethical", "noncompliant",
                    "obscured", "ambiguous", "omission", "opaque", "exploitative", "controversial", "wasteful",
                    "emissions", "brown", "reputational-risk", "climate-risk")
extra_words <- bind_rows(
  tibble(word = extra_positive, sentiment = "positive"),
  tibble(word = extra_negative, sentiment = "negative")
)
lexicon_loughran <- lexicon_loughran %>%
  bind_rows(extra_words) %>%
  distinct(word, sentiment)

# Tokenize each text into words and classify sentiment
sentiment_counts <- texts_df %>%
  unnest_tokens(word, text) %>%
  inner_join(lexicon_loughran, by = "word") %>%
  count(Our_Filenames, sentiment) %>%
  pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) %>%
  right_join(texts_df, by = "Our_Filenames") %>%
  mutate(
    positive = replace_na(positive, 0),
    negative = replace_na(negative, 0),
    net_sentiment = positive - negative
  )

#Normalize net_sentiment by total words
word_counts <- texts_df %>%
  mutate(total_words = str_count(text, "\\S+")) %>%
  select(Our_Filenames, total_words)

sentiment_counts <- sentiment_counts %>%
  left_join(word_counts, by = "Our_Filenames") %>%
  mutate(net_sentiment_normalized = net_sentiment / total_words)

# =============================================
# 4. Specificity Analysis
# =============================================
# List of vague generalities to search for (case-insensitive)
vague_terms <- c(
  # Generic praise
  "world-class", "best-in-class", "state-of-the-art", "leading\\b(?!\\s+practice)", "unmatched", 
  "industry-leading", "groundbreaking", "innovative solutions", "game-changer",
  
  # Emotional/aspirational
  "we care", "deeply committed", "making a difference", "passionate about", "in our DNA",
  "driven by purpose", "our values", "positive impact", "caring for the planet", "our mission",
  "sustainability is core", "at the heart of everything we do",
  
  # Vague actions
  "doing our part", "working towards", "taking steps", "on a journey", "moving forward", 
  "building a better future", "playing our role", "embracing change", "continuing our efforts", 
  "raising the bar", "setting the standard", "committed to change", "fostering dialogue",
  
  # Responsibility framing (without metrics)
  "responsible growth", "responsible business", "trusted partner", "transparent practices", 
  "ethical leadership", "stakeholder value", "values-driven", "long-term value creation", 
  "corporate citizenship", "aligned with our purpose",
  
  # ESG fluff
  "climate positive", "inclusive culture", "green future", "sustainable transformation", 
  "environmental stewardship", "diversity journey", "carbon-conscious", 
  "green economy", "eco-conscious", "climate action leadership", "just transition",
  
  # Future-oriented but vague
  "future generations", "better tomorrow", "future-focused", "next-generation", 
  "visionary goals", "looking ahead", "tomorrow’s challenges"
)

#To detect numbers, %, millions, etc. 
pattern_numbers <- "\\b(\\d+([\\.,]\\d+)?%?|\\$?€?\\d+([\\.,]\\d+)?\\s?(k|m|bn|million|billion)?)\\b"

specificity_df <- texts_df %>%
  mutate(
    numbers = str_count(text, regex(pattern_numbers, ignore_case = TRUE)),
    vague_count = sapply(text, function(t) {
      sum(str_count(t, regex(paste(vague_terms, collapse = "|"), ignore_case = TRUE)))
    }),
    specificity_index = numbers / (vague_count + 1)
  ) %>%
  select(Our_Filenames, numbers, vague_count, specificity_index)
# The specificity_index will be high if a report has a lot of numbers/names and few vague terms.

# =============================================
# 5. Buzzword Density
# =============================================

# Define a list of common ESG buzzwords to look for 
buzzwords_base <- c(
  "sustainable", "sustainability", "sustainable development", "green", "eco-friendly",
  "environment", "environmental", "social", "governance", "climate", "carbon", "climate change", 
  "net zero", "carbon neutral", "carbon footprint", "carbon offset", "low carbon", 
  "greenhouse gas", "emissions", "renewable", "clean energy", "solar", "wind", "hydro", 
  "diversity", "equity", "inclusion", "gender equality", "inclusive", "diverse", 
  "stakeholder", "employee engagement", "human rights", "fair labor", "supply chain", 
  "transparency", "ethical", "accountability", "integrity", 
  "impact", "social impact", "environmental impact", "positive impact", "purpose-driven", 
  "values-driven", "responsible", "sustainable value", "value creation", "long-term growth", 
  "resilience", "risk management", "stakeholder capitalism", 
  "sdgs", "sdg", "ungc", "gri", "sasb", "tcfd", "esg", "scope 1", "scope 2", "scope 3", 
  "materiality", "double materiality", "esg performance", "esg rating", "esg strategy",
  "just transition", "green economy", "climate leadership", "future generations", 
  "next-generation", "green future", "energy transition", "sustainable transformation"
)

# List of sustainability-related words coming from (https://www.dropbox.com/s/e28dihonntg8o82/expanded_dict.csv?e=1&dl=0)
sustainability_words <- c(
  "environment", "sustainability", "social", "waste", "biodiversity", "eco", "tourism", "biofuel",
  "bioplastic", "greenhouse", "effect", "carbon", "monoxide", "methane", "nitrogen", "oxide",
  "nitrate", "renewable", "resource", "energy", "production", "solar", "photovoltaic", "power",
  "wind", "hydroelectric", "hydropower", "geothermal", "desalination", "efficiency",
  "electrification", "clean", "water", "source", "panel", "turbine", "electrical", "consumption",
  "security", "system", "storage", "produce", "demand", "supply", "electricity", "pollution",
  "recycle", "emission", "underbanked", "unbanked", "conservation", "healthcare", "dioxide", "co",
  "money", "laundering", "act", "cryptocurrency", "interaction", "fertiliser", "quality",
  "initial coin offering", "ico", "impact", "circular", "ecosystem", "biogas", "alternative",
  "ozone", "smart", "city", "harmful", "protection", "savings", "problem", "underserved",
  "population", "economic", "entrepreneurship", "responsibility", "environmentally", "csr",
  "esg", "sdg", "health", "wellbeing", "farming", "public", "pollute", "poverty", "reduction",
  "food", "safety", "reduce", "save", "planet", "development", "governance", "authority",
  "administration", "leadership", "regulation", "policy", "oversight", "compliance",
  "management", "stewardship", "decision", "accountability", "transparency", "legislation",
  "executive", "legislative", "judicial", "service", "civic", "duty", "community", "society",
  "relationships", "communication", "networking", "cohesion", "integration", "belonging",
  "participation", "collaboration", "engagement", "inclusivity", "diversity", "equality",
  "welfare", "support", "solidarity", "cooperation"
)

#Merge both and remove duplicates
buzzwords <- unique(tolower(c(buzzwords_base, sustainability_words)))

# Count buzzwords in each text
buzz_df <- texts_df %>%
  # Tokenize by words to count individual word occurrences
  unnest_tokens(word, text) %>%
  mutate(word = tolower(word)) %>%
  # Filter to only buzzwords (for multi-word buzzwords like "net zero", they will appear as separate tokens "net" and "zero", -> for simplicity, we included single words and hyphenated as separate)
  filter(word %in% buzzwords) %>%
  count(Our_Filenames, name = "buzzword_count")

# Calculate buzzword density per 1000 words and number of unique buzzwords
buzz_metrics_df <- texts_df %>%
  mutate(total_words = str_count(text, "\\S+")) %>%
  left_join(buzz_df, by = "Our_Filenames") %>%
  mutate(
    buzzword_count = replace_na(buzzword_count, 0),
    buzzword_density = (buzzword_count / total_words) * 1000,
    # Unique buzzwords present in the text
    unique_buzzwords = sapply(text, function(t) {
      words <- tolower(str_split(t, "\\W+")[[1]])
      length(intersect(buzzwords, unique(words)))
    })
  ) %>%
  select(Our_Filenames, buzzword_count, buzzword_density, unique_buzzwords)

# =============================================
# 6. Hedging Language
# =============================================
# Define list of hedging terms (verbs that indicate aspiration or uncertainty)
hedge_words <- c(
  # Aspirational verbs
  "aim", "aiming", "aims", "aspire", "aspiring", "aspires", 
  "strive", "striving", "strives", "hope", "hoping", "hopes", 
  "intend", "intending", "intends", "plan", "planning", "plans", 
  "seek", "seeking", "seeks", "attempt", "attempting", "attempts", 
  "try", "trying", "tries", "work towards", "working toward", "envision", "envisioning", 
  
  # Modal verbs (probability / uncertainty)
  "may", "might", "could", "would", "should", "can", 
  "potentially", "possibly", "likely", "unlikely", "conceivably", "feasibly", 
  
  # Tentative / indirect expressions
  "believe", "think", "expect", "anticipate", "assume", 
  "hope", "estimate", "project", "suggest", "it is possible", 
  "there is a possibility", "endeavor", "committed to", "working on",
  
  # Uncertain adverbs/adjectives
  "broadly", "generally", "relatively", "approximately", "around", "somewhat", "partially",
  
  # PR-style softening
  "in the process of", "on the journey to", "in our efforts to", "as part of our commitment"
)

hedging_df <- texts_df %>%
  mutate(
    hedge_count = str_count(text, regex(paste0("\\b(", paste(hedge_words, collapse = "|"), ")\\b"), ignore_case = TRUE)),
    hedge_density = (hedge_count / str_count(text, "\\S+")) * 1000
  ) %>%
  select(Our_Filenames, hedge_count, hedge_density)

# =============================================
# 7. Candor and Transparency
# =============================================
#Define transparency / self-critical phrases
candor_phrases <- c(
  "did not meet", "fell short", "room for improvement", "areas for improvement",
  "lessons learned", "challenges remain", "we recognize we have more to do",
  "setbacks", "difficulty", "obstacle", "underperformed", "needs improvement",
  "risk of not", "lack of progress", "missed our target", "partial progress",
  "limited progress", "failed to achieve", "behind schedule"
)

# Candor Score's Computation (+ Normalized by report's length)

candor_df <- texts_df %>%
  mutate(
    word_count = str_count(text, "\\w+"),
    
    # Count of self-critical phrases
    candor_count = sapply(text, function(t) {
      sum(str_count(t, regex(paste(candor_phrases, collapse = "|"), ignore_case = TRUE)))
    }),
    
    # Raw frequency per 1000 words
    candor_density = ifelse(word_count > 0, (candor_count / word_count) * 1000, 0),
    
    # Min-max rescaling to [0,1]
    candor_score = rescale(candor_density, to = c(0, 1)),
    
    # Final risk-oriented score (low candor = high risk)
    candor_risk_component = 1 - candor_score
  ) %>%
  select(Our_Filenames, word_count, candor_count, candor_score, candor_risk_component)

# =============================================
# 8. Merge All Metrics with Metadata
# =============================================
final_data <- metadata %>%
  left_join(sentiment_counts %>% select(Our_Filenames, net_sentiment_normalized), by = "Our_Filenames") %>%
  inner_join(specificity_df, by = "Our_Filenames") %>%
  inner_join(buzz_metrics_df, by = "Our_Filenames") %>%
  inner_join(hedging_df, by = "Our_Filenames") %>%
  inner_join(candor_df, by = "Our_Filenames")
# Ensure no duplication of rows

#Replace NaN and NA with 0 to avoid calculation errors
final_data <- final_data %>%
  mutate(
    buzzword_density = replace_na(buzzword_density, 0),
    specificity_index = replace_na(specificity_index, 0),
    net_sentiment_normalized = replace_na(net_sentiment_normalized, 0),
    hedge_density = replace_na(hedge_density, 0),
    candor_risk_component = replace_na(candor_risk_component, 0)
  )


# =============================================
# 9. Construction of Greenwashing Score
# =============================================
## Tone / Sentiment Component
# Standardize net sentiment within each industry to get relative risk
final_data <- final_data %>%
  group_by(Industry) %>%
  mutate(sentiment_z = scale(net_sentiment_normalized)[,1]) %>%
  ungroup() %>%
  mutate(sentiment_risk_score = rescale(sentiment_z, to = c(0, 1)))

## Specificity Component
# Add total word count, calculate specificity density, apply log transform and normalize
final_data <- final_data %>%
  left_join(texts_df %>% select(Our_Filenames, text), by = "Our_Filenames") %>%
  mutate(total_words = str_count(text, "\\S+")) %>%
  # 1. Specificity density = how many numbers per 1000 words
  mutate(specificity_density = (numbers / total_words) * 1000) %>%
  # 2. Apply log-scaling
  mutate(specificity_log = log1p(specificity_density)) %>%
  # 3. Normalize to [0–1]
  mutate(specificity_score = rescale(specificity_log, to = c(0, 1)))

## Buzzword Component
# Standardize and normalize buzzword density by industry -> how much a report deviates from the average ESG buzzword density within its sector
final_data <- final_data %>%
  group_by(Industry) %>%
  mutate(buzzwords_score_industry_z = scale(buzzword_density)[,1]) %>% # z-score: std devs above/below mean
  # Normalize within industry (min–max) -> If we want all scores between 0 and 1 
  mutate(buzzwords_score_industry_norm = rescale(buzzword_density, to = c(0, 1))) %>%
  ungroup()

## Hedging Component
# Smooth and normalize hedging density
final_data <- final_data %>%
  mutate(hedging_smoothed = log1p(hedge_density)) %>% # smoother than raw ratio
  mutate(hedging_density_norma = rescale(hedging_smoothed, to = c(0, 1)))


## Composite Greenwashing Score
# Weighted average of five components
final_data <- final_data %>%
  mutate(greenwashing_score = (
    1.5 * buzzwords_score_industry_norm +
      1.2 * (1 - specificity_score) +
      1.0 * sentiment_risk_score +
      0.8 * hedging_density_norma +
      0.5 * candor_risk_component
  ) / (1.5 + 1.2 + 1.0 + 0.8 + 0.5)) %>%
  mutate(risk_category = case_when(
    greenwashing_score >= 0.75 ~ "High",
    greenwashing_score >= 0.5 ~ "Moderate",
    TRUE ~ "Low"
  ))

summary(final_data$greenwashing_score)

# =============================================
# 10. Multicollinearity Check and Component Correlations
# =============================================
# Required packages
install.packages("corrr")
install.packages("car")
library(corrr)
library(car)

# Create component dataset
#Correlation 
gws_w <- final_data %>%
  mutate(Specificity_Score = 1 - specificity_score) %>%
  select(
    buzzwords_score_industry_norm,
    Specificity_Score,
    sentiment_risk_score,
    hedging_density_norma,
    candor_risk_component,
  )
cor_matrix_gws_w <- cor(gws_w, method = "pearson", use = "pairwise.complete.obs")
round(cor_matrix_gws_w, 2)

# Correlation with GWS
gws <- final_data %>%
  mutate(Specificity_Score = 1 - specificity_score) %>%
  select(
    buzzwords_score_industry_norm,
    Specificity_Score,
    sentiment_risk_score,
    hedging_density_norma,
    candor_risk_component,
    greenwashing_score
  )

cor_matrix_gws <- correlate(gws)
rplot(cor_matrix_gws)
cor_matrix_gws_2 <- cor(gws, method = "pearson", use = "pairwise.complete.obs")
round(cor_matrix_gws_2, 2)
view(cor_matrix_gws_2)

# VIF analysis (For multicollinearity check in a regression context)
model <- lm(greenwashing_score ~ buzzwords_score_industry_norm + Specificity_Score + sentiment_risk_score + hedging_density_norma + candor_risk_component, data = gws)
vif(model) # VIF < 5 is generally acceptable

# =============================================
# 11. Comparison with GPT-based Greenwashing Score
# =============================================

library(readxl)
GPT_score <- read_excel("Downloads/GPT_GWS_Final_1.xlsx")
merged_df <- merge(final_data, GPT_score, by = "Our_Filenames")

# Pearson correlation
cor_value_ <- cor(merged_df$greenwashing_score, merged_df$GWS_gpt, use = "complete.obs", method = "pearson")
round(cor_value_, 3)

# Scatterplot
library(ggplot2)
ggplot(merged_df, aes(x = greenwashing_score, y = GWS_gpt)) +
  geom_point(alpha = 0.3, color = "orange") +
  geom_smooth(method = "lm", se = TRUE, color = "red") +
  labs(
    title = "Scatterplot of Rule-based GWS vs GPT-based GWS",
    x = "Rule-based Greenwashing Score (GWS)",
    y = "GPT-based Greenwashing Score (GWS_gpt)"
  ) +
  theme_minimal()


# Differences between component scores
Comparison_df <- data.frame(
  Our_Filenames = merged_df$Our_Filenames,
  
  Buzzword_NLP = merged_df$buzzwords_score_industry_norm,
  Buzzword_gpt = merged_df$buzzwords_score_gpt,
  Buzzword_Diff = merged_df$buzzwords_score_industry_norm - merged_df$buzzwords_score_gpt,
  
  Specificity_NLP = merged_df$specificity_score,
  Specificity_gpt = merged_df$specificity_score_gpt,
  Specificity_Diff = merged_df$specificity_score - merged_df$specificity_score_gpt,
  
  Sentiment_NLP = merged_df$sentiment_risk_score,
  Sentiment_gpt = merged_df$sentiment_score_gpt,
  Sentiment_Diff = merged_df$sentiment_risk_score - merged_df$sentiment_score_gpt,
  
  Hedging_NLP = merged_df$hedging_density_norma,
  Hedging_gpt = merged_df$hedging_score_gpt,
  Hedging_Diff = merged_df$hedging_density_norma - merged_df$hedging_score_gpt,
  
  Candor_NLP = merged_df$candor_score,
  Candor_gpt = merged_df$candor_score_gpt,
  Candor_Diff = merged_df$candor_score - merged_df$candor_score_gpt,
  
  GWS_NLP = merged_df$greenwashing_score,
  GWS_gpt = merged_df$GWS_gpt,
  GWS_Diff = merged_df$greenwashing_score - merged_df$GWS_gpt
)

summary(Comparison_df[, grep("_Diff$", names(Comparison_df))])

# Pearson correlations across all components
nlp_scores <- Comparison_df[, c("Buzzword_NLP", "Specificity_NLP", "Sentiment_NLP", "Hedging_NLP", "Candor_NLP", "GWS_NLP")]
gpt_scores <- Comparison_df[, c("Buzzword_gpt", "Specificity_gpt", "Sentiment_gpt", "Hedging_gpt", "Candor_gpt", "GWS_gpt")]
# We Change the name for more clarity in the matrix 
colnames(nlp_scores) <- paste0(c("Buzzword", "Specificity", "Sentiment", "Hedging", "Candor", "GWS"), "_NLP")
colnames(gpt_scores) <- paste0(c("Buzzword", "Specificity", "Sentiment", "Hedging", "Candor", "GWS"), "_GPT")
combined_scores <- cbind(nlp_scores, gpt_scores)
cor_matrix <- cor(combined_scores, method = "pearson", use = "complete.obs")

# =============================================
# 13. Event Study: CAR Analysis
# =============================================

# Summary statistics for CAR windows
summary(merged_df$CAR2)
summary(merged_df$CAR5)
summary(merged_df$CAR60)

# One-sample t-tests to test if mean CAR differs from 0
t.test(merged_df$CAR2, mu = 0)
t.test(merged_df$CAR5, mu = 0)
t.test(merged_df$CAR60, mu = 0)

# Compare CARs across event windows
library(tidyr)
long_cars <- merged_df %>%
  dplyr::select(Our_Filenames, CAR2, CAR5, CAR60) %>%
  pivot_longer(cols = -Our_Filenames, names_to = "window", values_to = "CAR")

# Visualize CAR distribution across windows
library(ggplot2)
ggplot(long_cars, aes(x = window, y = CAR)) +
  geom_boxplot() +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  labs(title = "Distribution of CARs Across Event Windows", x = "Event Window", y = "CAR") +
  theme_minimal()


# =============================================
# 14. Regression Models: CAR Explained by Greenwashing Scores
# =============================================

# --- Model 1: ESG Credibility and Market Reactions
reg_M1_CAR2_gpt <- lm(CAR2 ~ GWS_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR2_gpt)
reg_M1_CAR2_nlp <- lm(CAR2 ~ greenwashing_score + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR2_nlp)

reg_M1_CAR5_gpt <- lm(CAR5 ~ GWS_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR5_gpt)
reg_M1_CAR5_nlp <- lm(CAR5 ~ greenwashing_score + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR5_nlp)

reg_M1_CAR60_gpt <- lm(CAR60 ~ GWS_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR60_gpt)
reg_M1_CAR60_nlp <- lm(CAR60 ~ greenwashing_score + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M1_CAR60_nlp)

# --- Model 2: Interaction with ESG Performance: Contextualizing Greenwashing
reg_M2_CAR2_gpt <- lm(CAR2 ~ GWS_gpt * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR2_gpt)
reg_M2_CAR2_nlp <- lm(CAR2 ~ greenwashing_score * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR2_nlp)

reg_M2_CAR5_gpt <- lm(CAR5 ~ GWS_gpt * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR5_gpt)
reg_M2_CAR5_nlp <- lm(CAR5 ~ greenwashing_score * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR5_nlp)

reg_M2_CAR60_gpt <- lm(CAR60 ~ GWS_gpt * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR60_gpt)
reg_M2_CAR60_nlp <- lm(CAR60 ~ greenwashing_score * ESGscore + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M2_CAR60_nlp)

# --- Model 3: Disaggregated Linguistic Features: Testing the Components of Greenwashing
reg_M3_CAR2_gpt <- lm(CAR2 ~ sentiment_score_gpt + specificity_score_gpt + buzzwords_score_gpt + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR2_gpt)
reg_M3_CAR2_nlp <- lm(CAR2 ~ sentiment_risk_score + specificity_score + buzzwords_score_industry_norm + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR2_nlp)

reg_M3_CAR5_gpt <- lm(CAR5 ~ sentiment_score_gpt + specificity_score_gpt + buzzwords_score_gpt + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR5_gpt)
reg_M3_CAR5_nlp <- lm(CAR5 ~ sentiment_risk_score + specificity_score + buzzwords_score_industry_norm + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR5_nlp)

reg_M3_CAR60_gpt <- lm(CAR60 ~ sentiment_score_gpt + specificity_score_gpt + buzzwords_score_gpt + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR60_gpt)
reg_M3_CAR60_nlp <- lm(CAR60 ~ sentiment_risk_score + specificity_score + buzzwords_score_industry_norm + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + ESGscore + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M3_CAR60_nlp)

# --- Model 4: Interactions Between Linguistic Traits and ESG Context
reg_M4_CAR2_gpt <- lm(CAR2 ~ buzzwords_score_gpt * sentiment_score_gpt + specificity_score_gpt * ESGscore + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR2_gpt)
reg_M4_CAR2_nlp <- lm(CAR2 ~ buzzwords_score_industry_norm * sentiment_risk_score + specificity_score * ESGscore + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR2_nlp)

reg_M4_CAR5_gpt <- lm(CAR5 ~ buzzwords_score_gpt * sentiment_score_gpt + specificity_score_gpt * ESGscore + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR5_gpt)
reg_M4_CAR5_nlp <- lm(CAR5 ~ buzzwords_score_industry_norm * sentiment_risk_score + specificity_score * ESGscore + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR5_nlp)

reg_M4_CAR60_gpt <- lm(CAR60 ~ buzzwords_score_gpt * sentiment_score_gpt + specificity_score_gpt * ESGscore + hedging_score_gpt + candor_score_gpt + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR60_gpt)
reg_M4_CAR60_nlp <- lm(CAR60 ~ buzzwords_score_industry_norm * sentiment_risk_score + specificity_score * ESGscore + hedging_density_norma + candor_risk_component + log(1+SIZE) + ROA + MOMENTUM + as.factor(Industry) + as.factor(year), data = merged_df)
summary(reg_M4_CAR60_nlp)







