Code
library(tidyverse)
library(modelsummary)
library(marginaleffects)
library(broom)
firms <- read_csv("data/bisnode-firms.csv")Claudius Gräbner-Radkowitsch
June 16, 2026
June 16, 2026
This exercise accompanies the Logistic Regression for Binary Outcomes tutorial. Work through that page first.
Data: bisnode-firms.csv — ~17,500 Hungarian manufacturing and services firms. Download from gabors-data-analysis.com and place in a data/ subfolder.
Business question: Can we predict which firms are likely to exit the market in the next year?
Take two minutes to explore the data:
Rows: 17,506
Columns: 11
$ comp_id <dbl> 1002029, 1011889, 1014183, 1018301, 1022796, 1035705, 10…
$ exit <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0,…
$ sales_log <dbl> 13.943477, 12.980031, 11.773208, 8.813174, 10.169549, 10…
$ employees_log <dbl> -0.78015860, 0.48317409, -0.33508429, -1.87877086, -2.48…
$ profit_margin <dbl> 0.008554417, 0.223101892, -0.018128871, -0.164738285, -0…
$ age <dbl> 6, 20, 11, 8, 11, 1, 14, 5, 2, 4, 2, 1, 2, 4, 16, 1, 23,…
$ liquidity <dbl> 1.69277357, 8.46944789, 24.16025018, 3.05624997, 0.90785…
$ foreign <dbl> 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
$ female_ceo <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1,…
$ industry <dbl> 27, 55, 55, 56, 56, 56, 29, 56, 56, 27, 41, 55, 56, 28, …
$ urban <dbl> 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,…
Before coding: What does one row represent? What does exit = 1 mean?
Your answer:
Fit a logistic regression model that predicts firm exit using:
sales_log (log of sales revenue)profit_margin (profit as a share of sales)employees_log (log of number of employees)age (firm age in years)Call your model model_base.
1a. Which predictors are statistically significant at the 5% level?
Your answer:
1b. Based on the signs of the coefficients, which factors increase and which decrease the probability of exit? Does this make economic sense?
Your answer:
Add at least two more predictors to your model. Use subject-matter intuition: which firm characteristics might predict exit?
Compare your two models with modelsummary():
2a. Did adding the new predictors improve model fit? Use AIC to compare (lower is better).
Your answer:
2b. Did any coefficients shift notably when you added the new variables? What might that indicate?
Your answer:
Compute and display the odds ratios with 95% confidence intervals for your extended model:
Task 3: Choose one predictor and write a complete interpretation using this template:
“A one-unit increase in [variable] is associated with a multiplication of the odds of firm exit by [odds ratio]. This means the odds of exit [increase/decrease] by [X]%. This effect is [statistically significant / not significant] at the 5% level.”
Your answer:
Define two contrasting firm profiles and compute the predicted probability of exit for each:
# scenarios <- tibble(
# label = c("Profile A: ___", "Profile B: ___"),
# sales_log = c(___, ___),
# employees_log = c(___, ___),
# profit_margin = c(___, ___),
# age = c(___, ___)
# # add predictors you included in model_ext
# )
# scenarios |>
# mutate(pred_prob = predict(model_ext, newdata = scenarios, type = "response"))Task 4: Describe your two profiles and explain what story the predicted probabilities tell.
Your answer:
Write a short paragraph (3–5 sentences) summarising one key finding. Embed at least two numbers as inline R code (not typed manually).
Your paragraph:
Compare the AME for profit_margin from logistic regression to the LPM coefficient for the same variable. Are they similar? What does this tell you about when the LPM might be acceptable?
Your answer:
@inreference{graebner2026-exercise-logistic-regression-firm-exit,
author = {Gräbner-Radkowitsch, Claudius},
editor = {Gräbner-Radkowitsch, Claudius},
title = {Exercise: {Predicting} {Firm} {Exit} with {Logistic}
{Regression}},
booktitle = {Method and Inquiry},
date = {2026-06-16},
url = {https://euf-methodology-hub.netlify.app/resources/exercise-logistic-regression-firm-exit},
langid = {en}
}
---
title: "Exercise: Predicting Firm Exit with Logistic Regression"
description: "Practice logistic regression end-to-end: fit a model for binary firm exit, extend it with additional predictors, interpret odds ratios, compute scenario-based predicted probabilities, and communicate findings with inline R code."
author: "Claudius Gräbner-Radkowitsch"
date: 2026-06-16
date-modified: 2026-06-16
image: ../assets/images/r-programming.png
learning-objectives:
- "Fit and extend a logistic regression model with `glm()` and compare specifications using AIC"
- "Interpret a logistic regression coefficient as an odds ratio and communicate it in plain language"
- "Compute scenario-based predicted probabilities for two contrasting firm profiles"
- "Embed numerical results in written text using inline R code"
categories:
- R
- regression
- statistics
- exercise
- MA
level:
- MA
content-type: exercise
citation:
id: graebner2026-exercise-logistic-regression-firm-exit
type: entry-encyclopedia
container-title: "Method and Inquiry"
title: "Exercise: Predicting Firm Exit with Logistic Regression"
editor:
- name: "Claudius Gräbner-Radkowitsch"
url: https://euf-methodology-hub.netlify.app/resources/exercise-logistic-regression-firm-exit
---
::: {.callout-tip}
## Before you start
This exercise accompanies the [Logistic Regression for Binary Outcomes](logistic-regression-in-r.qmd) tutorial. Work through that page first.
**Data:** `bisnode-firms.csv` — ~17,500 Hungarian manufacturing and services firms. Download from [gabors-data-analysis.com](https://gabors-data-analysis.com/datasets/#bisnode-firms) and place in a `data/` subfolder.
**Business question:** *Can we predict which firms are likely to exit the market in the next year?*
:::
---
# Setup
```{r}
#| label: setup
#| message: false
library(tidyverse)
library(modelsummary)
library(marginaleffects)
library(broom)
firms <- read_csv("data/bisnode-firms.csv")
```
Take two minutes to explore the data:
```{r}
glimpse(firms)
```
**Before coding:** What does one row represent? What does `exit = 1` mean?
*Your answer:*
---
# Task 1: Fit a Logistic Regression Model
Fit a logistic regression model that predicts firm exit using:
- `sales_log` (log of sales revenue)
- `profit_margin` (profit as a share of sales)
- `employees_log` (log of number of employees)
- `age` (firm age in years)
Call your model `model_base`.
```{r}
# model_base <- ___
```
```{r}
# summary(model_base)
```
**1a.** Which predictors are statistically significant at the 5% level?
*Your answer:*
**1b.** Based on the signs of the coefficients, which factors increase and which decrease the probability of exit? Does this make economic sense?
*Your answer:*
---
# Task 2: Extend Your Model
Add at least **two more predictors** to your model. Use subject-matter intuition: which firm characteristics might predict exit?
```{r}
# names(firms) # explore available variables
```
```{r}
# model_ext <- ___
```
Compare your two models with `modelsummary()`:
```{r}
# modelsummary(list("Base" = model_base, "Extended" = model_ext), ...)
```
**2a.** Did adding the new predictors improve model fit? Use AIC to compare (lower is better).
*Your answer:*
**2b.** Did any coefficients shift notably when you added the new variables? What might that indicate?
*Your answer:*
---
# Task 3: Interpret Coefficients as Odds Ratios
Compute and display the odds ratios with 95% confidence intervals for your extended model:
```{r}
# exp(coef(model_ext))
# exp(confint(model_ext))
```
**Task 3:** Choose **one predictor** and write a complete interpretation using this template:
> *"A one-unit increase in [variable] is associated with a multiplication of the odds of firm exit by [odds ratio]. This means the odds of exit [increase/decrease] by [X]%. This effect is [statistically significant / not significant] at the 5% level."*
*Your answer:*
---
# Task 4: Predicted Probabilities for Two Firm Profiles
Define two contrasting firm profiles and compute the predicted probability of exit for each:
```{r}
# scenarios <- tibble(
# label = c("Profile A: ___", "Profile B: ___"),
# sales_log = c(___, ___),
# employees_log = c(___, ___),
# profit_margin = c(___, ___),
# age = c(___, ___)
# # add predictors you included in model_ext
# )
# scenarios |>
# mutate(pred_prob = predict(model_ext, newdata = scenarios, type = "response"))
```
**Task 4:** Describe your two profiles and explain what story the predicted probabilities tell.
*Your answer:*
---
# Task 5: Communicate a Finding with Inline R Code
Write a short paragraph (3–5 sentences) summarising one key finding. Embed at least **two numbers as inline R code** (not typed manually).
*Your paragraph:*
---
# Bonus: Average Marginal Effects
Compare the AME for `profit_margin` from logistic regression to the LPM coefficient for the same variable. Are they similar? What does this tell you about when the LPM might be acceptable?
```{r}
# avg_slopes(model_ext)
# lpm <- lm(exit ~ sales_log + profit_margin + employees_log + age, data = firms)
```
*Your answer:*