Statistical modelling is what R was built for, and formulas appear across its whole ecosystem.
Descriptive statistics are one call each: mean, median, sd, var, quantile, cor, and table or prop.table for counts. Classical tests are built in: t.test, wilcox.test, chisq.test, cor.test, each returning an object with a p-value and confidence interval.
Models use a formula: y ~ x1 + x2 reads "model y as a function of x1 and x2". Formula operators have special meanings:
x1:x2is an interaction,x1 * x2is both main effects plus the interaction.- 1removes the intercept;I(x^2)protects arithmetic inside a formula.- Factors are expanded into dummy variables automatically, using the first level as the reference.
fit <- lm(mpg ~ wt + hp, data = mtcars) fits ordinary least squares. Then use generic functions: summary(fit) for coefficients, standard errors and R squared, coef(fit), confint(fit), residuals(fit), predict(fit, newdata) and plot(fit) for diagnostics. anova(fit1, fit2) compares nested models.
glm(y ~ x, family = binomial, data = d) fits logistic regression and other generalised linear models with the same interface. The same formula idea drives aggregate, boxplot, t.test(value ~ group) and many packages, so learning it pays off widely.
Example
fit <- lm(mpg ~ wt + hp, data = mtcars)
print(round(coef(fit), 3))
#> (Intercept) wt hp
#> 37.227 -3.878 -0.032
print(round(summary(fit)$r.squared, 3)) #> [1] 0.827
new_cars <- data.frame(wt = c(2.5, 3.5), hp = c(100, 150))
print(round(predict(fit, new_cars), 1))
#> 1 2
#> 24.4 18.9
tt <- t.test(mpg ~ am, data = mtcars) # automatic vs manual
print(round(tt$p.value, 4)) #> [1] 0.0014
logit <- glm(am ~ wt, family = binomial, data = mtcars)
print(round(predict(logit, data.frame(wt = 3), type = "response"), 2))
#> 1
#> 0.49Remember
y ~ x1 + x2formulas describe models;*adds interactionslm/glmfit,summary/predict/confintinspect- Factors become dummy variables with the first level as reference
Watch out for
- Writing
y ~ x^2expecting a square term; inside formulas useI(x^2)orpoly(x, 2).