The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

OLSengine: Assisted Simplicity Tutorial

msoto-perez

2026-07-13

1. Introduction

The philosophy of Assisted Simplicity aims to bridge the gap between complex computation and methodological rigor. OLSengine provides six estimation engines in a single, unified interface: OLS regression, ANOVA/t-tests, logistic regression, panel data, instrumental variables (2SLS), and difference-in-differences.

All methods are implemented in pure base R with integrated Methodological Customs that audit assumptions and guide researchers toward robust alternatives.


2. OLS Regression: Handling Heteroskedasticity

In social sciences, variance often increases with the scale of the predictor. Let’s see how OLSengine detects and handles this.

library(OLSengine)

# Simulate data with non-constant variance
set.seed(123)
n <- 200
x <- rnorm(n, 50, 10)
y <- 10 + 0.5 * x + rnorm(n, 0, x * 0.2) # Heteroskedasticity

df <- data.frame(y, x)

# Run the engine
model <- paper_engine(y ~ x, data = df, model = "ols")
model$messages
## [1] "CRITICAL WARNING: Heteroskedasticity detected (Breusch-Pagan p < .05). Reported classic standard errors are biased. It is highly recommended to run the model with 'robust = TRUE' or 'robust = \"auto\"'."

Correcting with Robust Standard Errors

Following the Aduana’s advice, we apply HC3 robust standard errors:

model_robust <- paper_engine(y ~ x, data = df, model = "ols", robust = TRUE)
model_robust$tables$Table2_OLS_Estimation
##               Predictor    B   SE    t      p CI_95_Low CI_95_High   f2
## (Intercept) (Intercept) 9.70 4.28 2.27   0.02      1.26      18.14   NA
## x                     x 0.51 0.09 5.72 < .001      0.34       0.69 0.23
plot_engine(model_robust)


3. ANOVA/t-tests: Experimental Comparisons

In experimental research, we often compare groups. OLSengine automatically checks normality and variance homogeneity.

# Simulating 3 groups with non-normal distribution
set.seed(789)
group_data <- data.frame(
  score = c(rgamma(30, 2, 0.5), rgamma(30, 5, 0.5), rgamma(30, 3, 0.5)),
  group = rep(c("Control", "Treatment A", "Treatment B"), each = 30)
)

# Auto-pilot switches to non-parametric if normality fails
model_anova <- paper_engine(score ~ group, data = group_data, 
                            model = "anova", non_parametric = "auto")

model_anova$tables$Table4_Mean_Differences
##             Test     Metric Statistic df      p   Effect_Metric Effect_Size
## 1 Kruskal-Wallis Chi-square     42.93  2 < .001 Eta-squared (H)        0.47
plot_engine(model_anova)


4. Logistic Regression: Binary Outcomes

When the outcome is binary (e.g., Success/Failure), the engine calculates Odds Ratios, McFadden’s and Nagelkerke’s Pseudo R², and classification accuracy.

# Simulating binary data
set.seed(101)
n_logit <- 100
age <- rnorm(n_logit, 40, 10)
passed <- rbinom(n_logit, 1, plogis(-5 + 0.12 * age))

logit_df <- data.frame(passed, age)

# Run Logit engine
model_logit <- paper_engine(passed ~ age, data = logit_df, model = "logit")

model_logit$tables$Table2_Logit_Estimation
##               Predictor     B   OR   SE     z      p OR_CI_95_Low OR_CI_95_High
## (Intercept) (Intercept) -5.97 0.00 1.35 -4.42 < .001         0.00          0.04
## age                 age  0.14 1.15 0.03  4.41 < .001         1.08          1.23
model_logit$messages
## [1] "INFO: Classification Accuracy (Threshold 0.5) = 72.0%"          
## [2] "INFO: McFadden Pseudo R² = 0.207 | Nagelkerke Pseudo R² = 0.332"
plot_engine(model_logit)


5. Panel Data: Fixed and Random Effects

Panel data tracks the same entities over time. The Hausman test automatically selects between Fixed Effects (FE) and Random Effects (RE).

# Simulate panel data: 50 workers observed over 3 years
set.seed(456)
n_entities <- 50
n_time <- 3

panel_df <- data.frame(
  worker_id = rep(1:n_entities, each = n_time),
  year = rep(2018:2020, times = n_entities),
  wage = rnorm(n_entities * n_time, 50, 10) + 
         rep(rnorm(n_entities, 0, 5), each = n_time), # Entity fixed effect
  experience = rep(5:7, times = n_entities) + rnorm(n_entities * n_time, 0, 1)
)

# Hausman test decides between FE and RE
model_panel <- paper_engine(wage ~ experience, 
                            data = panel_df,
                            model = "panel",
                            entity_id = "worker_id",
                            time_id = "year",
                            method = "auto")

model_panel$tables[[1]]
##             Predictor    B   SE    t    p CI_95_Low CI_95_High
## experience experience 0.76 0.58 1.31 0.19     -0.39        1.9
model_panel$messages
## [1] "Customs Auto-Pilot: Hausman test supports random effects (p = 0.810). Random Effects estimator selected for efficiency gains (Wooldridge, 2010)."
## [2] "INFO: Panel structure - N entities = 50, T periods = 3, Total obs = 150"                                                                         
## [3] "INFO: R² (overall) = 0.000"                                                                                                                      
## [4] "INFO: Hausman test statistic = 0.06 (p = 0.810)"
plot_engine(model_panel)


6. Instrumental Variables: Addressing Endogeneity

When a predictor is correlated with the error term (endogeneity), Instrumental Variables (IV) provide consistent estimates using Two-Stage Least Squares (2SLS).

# Simulate IV data with endogeneity
set.seed(789)
n_iv <- 200

z <- rnorm(n_iv, 10, 3)  # Instrument
u <- rnorm(n_iv, 0, 2)   # Unobserved confounder

x <- 2 + 0.8 * z + u + rnorm(n_iv, sd = 1)  # Endogenous predictor
y <- 5 + 1.5 * x + u + rnorm(n_iv, sd = 3)  # Outcome

iv_df <- data.frame(y, x, z)

# 2SLS estimation
model_iv <- paper_engine(y ~ x, 
                         data = iv_df,
                         model = "iv",
                         instruments = ~ z)

model_iv$tables$Table2_IV_2SLS
##   Predictor   B  SE    t      p CI_95_Low CI_95_High
## x         x 1.4 0.1 13.7 < .001       1.2        1.6
model_iv$messages  # Reports first-stage F-stat
## [1] "INFO: First-stage F-statistic = 242.98 (> 10). Instruments pass relevance threshold (Stock & Yogo, 2005)."
## [2] "INFO: Exact identification (# instruments = # endogenous variables). Sargan test not applicable."         
## [3] "INFO: Sample size N = 200, Number of instruments = 1"                                                     
## [4] "INFO: R² = 0.724"
plot_engine(model_iv)


7. Difference-in-Differences: Causal Policy Evaluation

DiD estimates treatment effects by comparing changes over time between treated and control groups.

# Simulate policy intervention data
set.seed(321)
n_per_group <- 100

did_df <- data.frame(
  outcome = c(rnorm(n_per_group, 50, 10), rnorm(n_per_group, 53, 10),  # Control: pre/post
              rnorm(n_per_group, 50, 10), rnorm(n_per_group, 58, 10)), # Treated: pre/post
  group = rep(c("Control", "Treated"), each = n_per_group * 2),
  period = rep(c("Pre", "Post"), times = n_per_group * 2)
)

# DiD estimation
model_did <- paper_engine(outcome ~ 1, 
                          data = did_df,
                          model = "did",
                          treatment_var = "group",
                          time_var = "period",
                          treatment_level = "Treated",
                          post_level = "Post")

model_did$tables$Table2_DiD_Estimation
##                 Predictor     B   SE     t      p CI_95_Low CI_95_High
## (Intercept)   (Intercept) 51.08 1.04 49.10 < .001     49.04      53.13
## Treated           Treated  3.84 1.47  2.61   0.01      0.94       6.73
## Post                 Post  0.91 1.47  0.62   0.54     -1.99       3.80
## Treated:Post Treated:Post -0.26 2.08 -0.12   0.90     -4.35       3.83
model_did$tables$Group_Means
##     Group Time     Mean
## 1 Control  Pre 51.08468
## 2 Control Post 51.99048
## 3 Treated  Pre 54.92013
## 4 Treated Post 55.56740
model_did$messages  # Reports parallel trends test
## [1] "WARNING (Parallel Trends): Significant pre-treatment difference detected (p = 0.008). The parallel trends assumption may be violated. Consider including covariates or using alternative identification strategies (Roth et al., 2023)."
## [2] "INFO: DiD Effect (Treated:Post interaction) = -0.259 (SE = 2.081, p 0.90)"                                                                                                                                                              
## [3] "INFO: Sample size N = 400"                                                                                                                                                                                                              
## [4] "INFO: R² = 0.032"
plot_engine(model_did)


8. Real Data Example: Academic Salaries

The package includes a real dataset of 397 U.S. college professors.

data(academic_salaries)

# Explore salary determinants
salary_model <- paper_engine(salary ~ rank + discipline + years_since_phd + sex,
                             data = academic_salaries,
                             model = "ols",
                             robust = "auto")

salary_model$tables$Table2_OLS_Estimation
##                       Predictor        B      SE     t      p CI_95_Low
## (Intercept)         (Intercept) 67884.32 2784.30 24.38 < .001  62410.24
## rankAssocProf     rankAssocProf 13104.15 2243.19  5.84 < .001   8693.92
## rankProf               rankProf 46032.55 3359.53 13.70 < .001  39427.55
## disciplineB         disciplineB 13937.47 2372.64  5.87 < .001   9272.73
## years_since_phd years_since_phd    61.01  155.64  0.39   0.70   -244.99
## sexMale                 sexMale  4349.37 2423.53  1.79   0.07   -415.42
##                 CI_95_High   f2
## (Intercept)       73358.40   NA
## rankAssocProf     17514.38 0.03
## rankProf          52637.55 0.30
## disciplineB       18602.21 0.09
## years_since_phd     367.02 0.00
## sexMale            9114.15 0.00
salary_model$messages
## [1] "Customs Auto-Pilot: Heteroskedasticity detected (p < .05). Robust Standard Errors (HC3) were applied automatically (Hayes & Cai, 2007)."                             
## [2] "INFO (Multicollinearity): Maximum VIF = 3.07. Moderate collinearity detected but below critical threshold. Standard errors may be slightly inflated (O'Brien, 2007)."
## [3] "WARNING (Normality): p < .05 in Shapiro-Wilk. With N=397, OLS may be robust due to CLT (Lumley et al., 2002)."

Conclusion

OLSengine simplifies the transition from raw data to paper-ready results across six estimation methods. Every step is backed by rigorous methodological audits, ensuring researchers can focus on interpretation rather than implementation.

Key Features: - Zero external dependencies (pure base R) - Integrated diagnostics with actionable warnings - APA-formatted tables and publication-ready plots - Unified interface across OLS, ANOVA, Logit, Panel, IV, and DiD

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.