
Statistical analysis with plain-English interpretation for R
statease runs common statistical tests and returns each result together with a plain-English interpretation, the effect size, the significance decision, and, as of v1.4.0, a set of assumption checks relevant to that specific test, shown by default rather than as an optional extra step.
statease does not replace statistical judgment. It cannot know your study design, whether your sample was randomly selected, or whether an assumption violation matters for your particular use case, no automated tool can. What it does is surface the diagnostic information a careful analyst would normally have to compute separately (normality, variance homogeneity, multicollinearity, and several others depending on the test), clearly labelled as PASSED, WARNING, or NOTE, so that information is in front of you at the moment you read the result rather than something you have to remember to go check yourself.
You can also describe your study design in a sentence, and statease will echo it back alongside the interpretation as a reminder to read the result in that context:
ttest_interpret(x, y, context = "observational sample, not randomized")install.packages("statease")For the development version from GitHub:
# install.packages("devtools")
devtools::install_github("DevWebWacky/statease")Try statease directly in your browser without installing R:
đ Launch statease Shiny App
| Function | What it does |
|---|---|
analyze() |
Master function - auto-detects and runs the right test |
describe() |
Descriptive statistics with interpretation |
ttest_interpret() |
T-tests, with normality and variance checks by default |
anova_interpret() |
One-way ANOVA with Tukey post-hoc, eta squared, and assumption checks |
anova2_interpret() |
Two-way ANOVA with Type II/III SS and assumption checks |
manova_interpret() |
MANOVA with Pillaiâs trace and follow-up ANOVAs |
chisq_interpret() |
Chi-square test with Cramerâs V and expected-frequency checks |
fisher_interpret() |
Fisherâs Exact Test with Odds Ratio |
mcnemar_interpret() |
McNemarâs Test for paired categorical data |
cor_interpret() |
Correlation (Pearson, Spearman, Kendall) with linearity notes |
reg_interpret() |
Simple linear regression with normality, homoscedasticity, and independence checks |
mlr_interpret() |
Multiple linear regression, adding multicollinearity (VIF) checks |
logistic_interpret() |
Logistic regression with odds ratios and a separation diagnostic |
mannwhitney_interpret() |
Mann-Whitney U test (non-parametric) |
wilcoxon_interpret() |
Wilcoxon Signed Rank test (non-parametric) |
kruskal_interpret() |
Kruskal-Wallis test with post-hoc comparisons |
friedman_interpret() |
Friedman Test with Kendallâs W |
check_assumptions() |
Run the same assumption checks on their own, before choosing a test |
power_interpret() |
Statistical power analysis and sample size calculation |
interpret_p() |
Standalone p-value interpreter |
library(statease)
# Descriptive statistics
analyze(x = c(23, 45, 12, 67, 34), var_name = "Exam Scores")
# Independent samples t-test (auto-detected), with a study design note
analyze(x = c(23,45,12,67,34), y = c(19,38,22,51,29),
var_name = "Scores",
context = "convenience sample, not randomly assigned")
# Check assumptions before deciding on a test
analyze(x = c(23,45,12,67,34), y = c(19,38,22,51,29),
check = TRUE)
# Non-parametric alternative (auto-detected)
analyze(x = c(23,45,12,67,34), y = c(19,38,22,51,29),
nonparam = TRUE, var_name = "Scores")
# Correlation (auto-detected)
analyze(x = c(23,45,12,67,34), y = c(19,38,22,51,29),
var1_name = "Exam Score", var2_name = "Study Hours")
# Chi-square (auto-detected)
analyze(
x = c("Yes","No","Yes","Yes","No"),
y = c("Male","Female","Male","Female","Male")
)
# One-way ANOVA (auto-detected)
df <- data.frame(
score = c(23,45,12,67,34,89,56,43,78,90,11,34),
group = rep(c("A","B","C"), each = 4)
)
analyze(formula = score ~ group, data = df)
# Two-way ANOVA (auto-detected)
df2 <- data.frame(
score = c(23,45,12,67,34,89,56,43,78,90,11,34),
method = rep(c("Online","Traditional"), each = 6),
gender = rep(c("Male","Female"), times = 6)
)
analyze(formula = score ~ method * gender, data = df2)
# Simple linear regression (auto-detected)
df3 <- data.frame(
exam_score = c(23,45,12,67,34,89,56,43,78,90),
study_hours = c(2,5,1,7,3,9,6,4,8,10)
)
analyze(formula = exam_score ~ study_hours, data = df3)
# Power analysis
analyze(test_type = "ttest.two", effect_size = 0.5)
# Interpret any p-value
interpret_p(0.03, context = "treatment vs control group")Every relevant _interpret() function prints its
assumption checks automatically, whether or not anything is wrong:
Assumption Checks:
Normality (Group 1) : PASSED (Shapiro-Wilk p = 0.342)
Normality (Group 2) : WARNING (Shapiro-Wilk p = 0.012, may not be normal)
Equal variances : PASSED (Levene's p = 0.501)
NOTE: Assumption checks are diagnostic tools and may be
influenced by sample size and other characteristics of the
data. Passing a check does not prove that an assumption is
satisfied, and a warning does not automatically invalidate
the analysis. Interpret these results alongside your
knowledge of the data.
Checks are labelled one of three ways: - PASSED : the package tested this and found no evidence of a problem - WARNING : the package detected something worth your attention - NOTE : something relevant to interpretation that the package cannot test automatically (independence of observations, for example, is a property of how the data was collected, not something computable from the numbers themselves)
Most R output gives you numbers. statease gives you numbers, a plain-English interpretation, and by default, the assumption context needed to read that interpretation responsibly. Itâs built for: - Students learning statistics - Researchers who want fast, readable output without skipping diagnostics - Educators teaching statistical concepts
_interpret() function, rather than requiring a separate
call to check_assumptions()context argument across all inferential
functions and analyze(), letting users describe their study
design and have it echoed back alongside the interpretationlogistic_interpret()reg_interpret() and mlr_interpret() now
check homoscedasticity and residual independence in addition to
normality; mlr_interpret() also checks multicollinearity
(VIF)check_assumptions()âs regression logic now shares its
diagnostic calculations with reg_interpret() and
mlr_interpret(), rather than three separate
implementationspower_interpret() where an
effect size exactly equal to a Cohenâs convention threshold was labelled
one category too highanova2_interpret()âs printed report
did not display the Sum of Squares typechisq_interpret() triggered Râs
internal chi-squared approximation warning twicelm()/glm() fitted inside
a wrapper function could cause car::ncvTest() to fail
silently when computing homoscedasticityfisher_interpret() for Fisherâs Exact Testmcnemar_interpret() for McNemarâs Testfriedman_interpret() for Friedman Testcheck_assumptions() for automated assumption
checkingpower_interpret() for power analysis and sample
sizerun_app() for point-and-click
analysisanalyze() with check and
test_type argumentsmlr_interpret() for multiple linear
regressionlogistic_interpret() for logistic regressionmanova_interpret() for MANOVAmannwhitney_interpret() for Mann-Whitney U
testwilcoxon_interpret() for Wilcoxon Signed Rank
testkruskal_interpret() for Kruskal-Wallis testanalyze() with nonparam
argumentchisq_interpret() for chi-square testscor_interpret() for correlation analysisreg_interpret() for simple linear regressionanova2_interpret() for two-way ANOVAanalyze() to auto-detect all new testsdescribe(), ttest_interpret(),
anova_interpret(), interpret_p(),
analyze()MIT