Opens in a new tab

METHOD GUIDE

Chi-Square Test in R
The Continuity Correction and Small-Count Warnings

For a 2×2 table, chisq.test() applies a continuity correction unless told otherwise, and it warns when the large-sample approximation may be unreliable. Knowing which of the two happened to your table settles which p-value you report.

IN SHORT

What the Test Compares and What R Does by Default

The chi-square test compares the counts observed in a contingency table with the counts expected if two categorical variables were unrelated, and it asks whether the data give evidence of an association. To run a chi-square test in R, build a table of counts with table(), pass it to chisq.test(), and read the statistic, degrees of freedom and p-value together with any warning, since a 2×2 table is corrected for continuity unless correct = FALSE is set. The test needs one count per case and frequencies, not percentages. OnlineSPSS, a specialist statistical consultancy for academic, clinical and professional research, carries out and reviews this analysis through an in-house PhD-level statistician.

ANALYSIS SUPPORT

Analysis Support for This Method

R applies a continuity correction to a 2×2 table without being asked and warns when counts are small, but whether this is the right test is decided from the design first.

Chi-Square Test

The chi-square test for your table, with the expected frequencies, the choice of exact or approximate p and the effect size settled before the analysis starts.

Explore Chi-Square Test
Fisher's Exact Test

An exact test of association for tables with small counts, for when expected frequencies fall too low for the chi-square approximation to be dependable.

Explore Fisher's Exact Test

BEFORE YOU RUN IT

Preparing the Table That chisq.test() Will Read

What the function does depends on whether it is handed a table, a pair of factors or a single vector, so the input is built deliberately and inspected before the test is run.

Counts of Whole Cases The function needs frequencies of independent cases. Percentages or proportions in a matrix change the sample size the test sees, and the statistic then describes a dataset that does not exist.

Table, Two Factors or One Vector Two factors, or a table made from them, give a test of association. A single vector of counts is read as a goodness-of-fit test against equal probabilities, which is a different question.

Each Case Counted Once Each case sits in one cell once. Before and after measures on the same people call for McNemar's test, and clustered participants need a method that allows for the clustering.

Correction Chosen in Advance The continuity correction makes the 2×2 test more conservative, and opinions differ on whether it is needed. The version, or an exact test, is chosen before the p-value is seen and then named.

IN R

How to Run a Chi-Square Test in R

Running chisq.test in R needs only base R for the test, the expected frequencies and the residuals. Effect size functions come from add-on packages, so each package and its version are recorded with the script.

  1. Confirm the design: two categorical variables and each case counted once.
  2. Build the table with tab <- table(d$a, d$b) and print prop.table(tab, 1) for row percentages.
  3. Run res <- chisq.test(tab), with correct = FALSE only if the uncorrected version was chosen in advance.
  4. Print res$expected and count how many cells fall below 5.
  5. If counts are small, use fisher.test(tab) or chisq.test(tab, simulate.p.value = TRUE, B = 10000).
  6. Add Cramér’s V from an add-on such as rstatix or effectsize, and inspect res$stdres for the cells that drive the result.

READING THE OUTPUT

The chisq.test Header, Warning and Residuals

The header names the version that ran, the warning refers to the expected frequencies, and the residuals sit inside the object and are not printed.

Output element What it tells you What to check
Header line Pearson’s Chi-squared test, with or without Yates’ continuity correction Which version ran, and that the methods name it
X-squared, df and p-value The statistic, df equal to (rows minus 1) times (columns minus 1), and the asymptotic p That df matches the shape of the table
Warning: Chi-squared approximation may be incorrect At least one expected frequency is below 5, so the large-sample approximation is doubtful Which cells are small, and whether to use an exact test, simulate or merge categories on substantive grounds
Header with simulated p-value A Monte Carlo p-value from the stated number of replicates, with df shown as NA That B is stated and a seed is set for reproducibility
res$expected The expected frequencies in R under no association That the smallest value is reported
res$residuals Pearson residuals, observed minus expected divided by the square root of expected That they are not read as separate tests of significance
res$stdres Standardized residuals, approximately standard normal when the null holds and counts are not small That a few large values among many cells are labeled exploratory
Effect size from an add-on Cramér’s V or phi, and for a 2×2 table an odds ratio That the package is named and the type of any interval is read from its documentation

REPORTING

Reporting the Statistic, the Version and V

A reader needs to know which version of the p-value was computed, and that single clause is the one most often missing.

Write χ²(df, N = ___) = ___, p = ___, and name the version: Pearson’s test, Pearson’s test with Yates’ continuity correction, or a Monte Carlo p-value with its number of replicates. Report Cramér’s V = ___ for tables larger than 2×2, or the odds ratio with its 95% CI [___, ___] for a 2×2 table, and name the function that produced it, since chisq.test() prints neither and fisher.test() gives a conditional estimate of the odds ratio. Show the counts with percentages in the direction of the comparison, and state the smallest expected frequency and the share of cells below 5. If individual cells are discussed, report the standardized residuals as exploratory and say how many cells were inspected. Keep the wording to association.

Version of the Test Namedχ² With df and NEffect SizeSmallest Expected FrequencyResiduals as Exploratory

COMMON MISTAKES

Choices R Makes That Reports Forget to Mention

A default is not a mistake, but an unreported default is, and so is a warning that was seen and not acted on.

Correction Reported as the Test A result copied from the corrected header is described as a plain Pearson chi-square. The correction changes the statistic and the p-value, so the report states which version was used.

Warning Scrolled Past The expected-frequency message prints after the result in the console. A report that ignores it may rest on an approximation that does not hold for the sparse cells.

Simulation Without a Seed A Monte Carlo p-value changes slightly on every run. Setting a seed with set.seed() before the call, and stating the replicates, makes it reproducible.

Percentages in the Wrong Direction Row and column percentages give different comparisons. They are calculated in the direction of the explanatory variable and labeled, so the reader sees the intended contrast.

Observed Counts Checked Instead of Expected The guideline concerns the expected frequencies in res$expected, not the observed counts in the table. A cell with few observed cases can have an adequate expected value, and the reverse also happens.

Trend Missed in Ordered Categories When both variables are ordered, the chi-square test ignores the order. A test for trend across ordered categories answers the question more directly and often with more power.

Seen the small-count warning? Independent Statistical Review checks the version of the test, the expected frequencies and the effect size against the script.

Request an Assessment

FREQUENTLY ASKED QUESTIONS

Questions About chisq.test() Warnings and Options

The first answer follows the warning back to the cells that caused it, and the other two cover the correction and simulated p-values.

The warning means at least one expected frequency is below 5, and res$expected shows which cells. Count them and report the smallest. The cutoff of 5 is a convention, and a table just past it is not suddenly invalid. Options are an exact test, a Monte Carlo p-value or merging categories on substantive grounds, chosen before looking at which one gives the p-value you hoped for.

The function chisq.test() applies Yates’ correction by default only to 2×2 tables, through the argument correct = TRUE. It subtracts one half from each absolute difference between observed and expected counts, which makes the p-value larger. Setting correct = FALSE gives the uncorrected test, and fisher.test() gives an exact alternative. Report which version was used.

The p-value is then computed by Monte Carlo sampling of tables with the same totals and not from a chi-squared distribution, so the degrees of freedom are shown as NA. The result can vary slightly between runs unless a seed is set. Report the number of replicates, the seed and that the p-value is simulated.

You do, with advice: an in-house PhD-level statistician can look at the expected frequencies and the design, explain which version fits and why, and run the analysis on your data. Presenting settled counts and effect sizes in your results is the work of Results Reporting & Interpretation. The interpretation stays with you.

Your data and project details are handled confidentially, and project information is not published. Researcher names and institutions are not used publicly without permission. An NDA is available where required and can be arranged before sensitive materials are shared. Read more about confidentiality and data security.

You share your research question, design and relevant materials, such as the dataset or the output you have, and a statistically trained Research Coordinator reviews the request and responds the same day. The analysis, deliverables, timeline and one fixed project fee are then confirmed before any work begins, so the timeline follows from the agreed scope.

Still have a question? Find more answers in our full FAQ.

View All FAQs →

NEXT STEP

Is the Right p-Value
in Your Chi-Square Draft?

Whether a corrected, exact or simulated p-value belongs in the methods depends on the table and the design. A statistically trained Research Coordinator responds to the request the same day.

No Commitment Required

Strictly Confidential

Fixed Project Fee

In-House PhD-Level Statisticians

Same-Day Response

Serving Researchers Since 2014