# Creates bisnode-firms.csv: one row per firm, for Session 11 (classification).
#
# Source: cs_bisnode_panel.csv — panel of Hungarian firms, 2005–2016, from the
#         data repository of Békés & Kézdi (2021), Data Analysis for Business,
#         Economics, and Policy, on OSF: https://osf.io/7epdj/
#         (folder bisnode-firms; downloaded 12 October 2026; CC BY-NC-SA 4.0).
#
#         The panel is NOT in this repository (too large). To re-run this
#         script, download cs_bisnode_panel.csv and put it next to this file.
#
# Strategy:
#   - Take all firms observed in 2012 (cross-section year)
#   - Define exit = 1 if the firm is absent from the 2013 panel
#     (panel-based definition; captures both formal dissolution and firms that
#      simply stopped filing — exit rate ~7%). Note: Békés & Kézdi, ch. 17,
#     use a two-year horizon (2012 to 2014); this file uses one year.
#   - Compute derived variables used in the demo and exercise
#   - Apply basic quality filters (positive sales, valid age, etc.)
#   - Output: 17,506 firms, 11 variables, < 2 MB
#
# Variable notes:
#   urban = 1 if urban_m == 1 in the source, i.e. the firm is located in the
#           capital, Budapest (not "urban" in general).
#   employees_log can be negative: labor_avg is an annual average and can be
#           below one person.

# ADJUST THIS LINE: the path is where the script sits in the course repository.
# In your own project, write where you saved it, e.g. here::i_am("prepare_bisnode.R"),
# and change the two here("sessions", "session11", "data", ...) paths below to match.
here::i_am("sessions/session11/data/prepare_bisnode.R")
library(here)
library(tidyverse)

# ── 1. Load raw panel ─────────────────────────────────────────────────────────

raw <- read_csv(
  here("sessions", "session11", "data", "cs_bisnode_panel.csv"),
  show_col_types = FALSE
)

# ── 2. Cross-section: firms observed in 2012 ─────────────────────────────────

# Panel-based exit: a firm "exited" if it appears in 2012 but not in 2013.
# exit_year captures only formal dissolution and misses many true exits.
ids_active_2013 <- raw |>
  filter(year == 2013) |>
  pull(comp_id)

firms_2012 <- raw |>
  filter(year == 2012) |>
  mutate(exit = as.integer(!comp_id %in% ids_active_2013))

# ── 3. Derive variables ───────────────────────────────────────────────────────

firms <- firms_2012 |>
  mutate(
    # Log sales (revenue); NA if sales <= 0 (filtered below).
    # The condition sits inside log() so non-positive values become NA before
    # log() is called — avoids the NaN warning from if_else()'s eager evaluation.
    sales_log = log(if_else(sales > 0, sales, NA_real_)),

    # Log employees; labor_avg is the average number of employees
    employees_log = log(if_else(labor_avg > 0, labor_avg, NA_real_)),

    # Profit margin: annual profit/loss as a share of sales,
    # capped at [-1, 1] to limit the influence of extreme values
    profit_margin = if_else(
      sales > 0,
      pmin(pmax(profit_loss_year / sales, -1), 1),
      NA_real_
    ),

    # Firm age in years at the cross-section year
    age = 2012L - founded_year,

    # Liquidity ratio: current assets / current liabilities
    liquidity = if_else(curr_liab > 0, curr_assets / curr_liab, NA_real_),

    # Foreign-owned firm (binary)
    foreign = as.integer(foreign == 1),

    # Female CEO (binary)
    female_ceo = as.integer(female == 1),

    # Industry (2-digit NACE code)
    industry = ind2,

    # Located in Budapest (urban_m == 1 in the source)
    urban = as.integer(urban_m == 1)
  )

# ── 4. Quality filters ────────────────────────────────────────────────────────

firms_clean <- firms |>
  filter(
    !is.na(sales_log),      # need valid sales
    !is.na(employees_log),  # need valid employment
    !is.na(profit_margin),  # need valid profit margin
    age >= 0,               # no negative ages
    age <= 100              # drop implausibly old firms
  )

# ── 5. Select output variables ────────────────────────────────────────────────

firms_out <- firms_clean |>
  select(comp_id, exit, sales_log, employees_log, profit_margin, age,
         liquidity, foreign, female_ceo, industry, urban)

# ── 6. Quick sanity check ─────────────────────────────────────────────────────

cat("Rows:", nrow(firms_out), "\n")
cat("Exit rate:", round(mean(firms_out$exit), 3), "\n")
cat("NAs per column:\n")
print(colSums(is.na(firms_out)))

# ── 7. Save ───────────────────────────────────────────────────────────────────

write_csv(firms_out, here("sessions", "session11", "data", "bisnode-firms.csv"))
cat("Saved to sessions/session11/data/bisnode-firms.csv\n")
