Written and maintained by CASRAI Editorial Board
Last updated
The chi-square test in R is run with chisq.test() from the stats package, which ships with base R. The same function handles a chi-squared test of goodness of fit (one vector of counts) and a chi-squared test of independence (a table of counts with at least two rows and two columns). This page is a function-level reference: what each argument does in each mode, what the returned object contains, and what to switch to when counts are small. (Searchers also write this as chi square test in R, chi squared test in R, or chi-squared test in R; they are all the same function.)
What it is used for in research
In research, chisq.test() answers two kinds of question about counts. The first is whether observed category counts match a set of expected proportions (goodness of fit). The second is whether two categorical variables are associated, which the R manual describes as testing whether the joint distribution of the cell counts equals the product of the row and column marginals (independence). For the concepts behind the test, see the chi-square test guide; for worked interpretation, see chi-squared examples. For R in general across t, chi-square and rank tests, see hypothesis testing with R.
Install or access (official source only)
Nothing needs installing: chisq.test() is documented in the R stats manual (chisq.test reference page) and is available in any R session. Typing ?chisq.test opens the same help page locally. A tidy, data-frame-returning wrapper, chisq_test(), is available in the rstatix package from CRAN (install.packages("rstatix")); its reference is at rpkgs.datanovia.com/rstatix.
Step-by-step: running chisq.test() in R
The full call signature in the manual is:
chisq.test(x, y = NULL, correct = TRUE,
p = rep(1/length(x), length(x)), rescale.p = FALSE,
simulate.p.value = FALSE, B = 2000)
Which mode will R use?
R chooses the mode from the shape of x. Per the manual, a goodness-of-fit test is run when x is a vector with no y, or a matrix with a single row or column. A test of independence is run when x is a matrix with at least two rows and two columns, or when x and y are both vectors or factors of the same length (they are coerced to factors and cases with missing values are dropped). If x is a matrix, y is ignored. Counts must be non-negative integers.
Chi-squared goodness-of-fit test in R
- Put the observed counts in a numeric vector, for example
counts <- c(81, 50, 27). - If you expect equal proportions, call
chisq.test(counts). Whenpis omitted, all categories are expected to be equally likely. - If you expect other proportions, pass them in
p, one per element ofx:chisq.test(counts, p = c(1/2, 1/3, 1/6)). - If your
pvalues are relative weights that do not sum to 1, addrescale.p = TRUE. The manual states that withrescale.p = FALSE, apthat does not sum to 1 gives an error, and negative entries inpalso give an error.
Chi-squared test of independence in R
- From a table of counts, build a matrix:
tab <- matrix(c(12, 5, 7, 7), ncol = 2), then callchisq.test(tab). - From two columns of raw data, pass them as
xandy:chisq.test(df$gender, df$smoker), or cross-tabulate first withtable(); see crosstabs in R. - For a 2 x 2 table R applies a continuity correction by default (
correct = TRUE). To turn it off, usecorrect = FALSE; background is in continuity corrections.
Raw observations: use table(), not the vector itself
The manual’s own example makes the point: if x holds raw observations (one entry per case) rather than counts, run chisq.test(table(x)). Calling chisq.test(x) on raw values treats each value as a count, which is a different test.
Argument map: which arguments act in which mode
| Argument | Goodness of fit | Independence | What the manual says |
|---|---|---|---|
p |
Used | Not used | Expected probabilities, one per element of x; must not be negative. |
rescale.p |
Used | Not used | If TRUE, p is rescaled to sum to 1; if FALSE and the sum is not 1, an error results. |
correct |
Not used | 2 x 2 tables only | Subtracts half of each |O – E| (capped at the difference itself); not applied when simulate.p.value = TRUE. |
simulate.p.value |
Used | Used | Monte Carlo p-value from B replicates (default 2000). |
B |
Used with simulation | Used with simulation | Number of Monte Carlo replicates; smallest possible p-value is about 1/(B + 1). |
Output and how to read it
The function returns an object of class htest. Assign it to a name (res <- chisq.test(tab)) and read its parts with $.
| Component | What it holds |
|---|---|
$statistic |
The chi-squared test statistic. |
$parameter |
Degrees of freedom; NA when the p-value is simulated by Monte Carlo. |
$p.value |
The p-value. |
$method, $data.name |
Text describing the test run and the data supplied. |
$observed |
The observed counts (the input). |
$expected |
Expected counts under the null hypothesis. |
$residuals |
Pearson residuals, (O – E) / sqrt(E). |
$stdres |
Standardized residuals, (O – E) / sqrt(V), where V is the residual variance. |
Read $p.value against your pre-set significance level, then look at $expected to check that no cell is tiny, and at $stdres to see which cells drive a significant result (see standardized residuals). For an effect size that does not grow with sample size, see Cramer’s V; to read the table itself, see how to read a contingency table.
Small counts: asymptotic, simulated or exact
The default p-value uses the chi-squared approximation. Two alternatives are documented in the R manuals.
- Simulated p-value.
simulate.p.value = TRUEcomputes the p-value by Monte Carlo. For a contingency table, the manual says random tables are generated with fixed marginals (which must be strictly positive) and no continuity correction, in a way that resembles the sampling used by Fisher’s exact test. For goodness of fit it draws samples of sizesum(x)fromp; the manual says this simulation is done in R and “may be slow”. - Fisher’s exact test.
fisher.test()tests independence of rows and columns with fixed marginals. For tables larger than 2 x 2 it has its ownsimulate.p.valueoption, and the manual notes that an r x c table can be too large for the exact calculation, in which case an error is signalled; raising the workspace can take hours, and simulation is described as often sufficient and advisable. Itshybrid = TRUEoption uses the chi-squared approximation only when Cochran’s conditions are met (defaults inhybridPars: expect = 5, percent = 80, Emin = 1). See Fisher testing.
The manual’s own worked example shows how far the approaches can differ. For matrix(c(12, 5, 7, 7), ncol = 2), the asymptotic p-value is 0.4233, while a simulated p-value with B = 10000 comes out around 0.29. With a simulated p-value, the smallest value you can ever obtain is about 1/(B + 1), so with the default B = 2000 you cannot report p much below 0.0005; raise B if you need to resolve smaller values.
Tidy output with rstatix::chisq_test()
The rstatix function chisq_test() adds a vars argument and returns a data frame with columns including n, statistic, df (NA for Monte Carlo), p, p.adj, method, p.signif, observed and expected. Its reference page shows these calls:
library(rstatix)
tulip <- c(red = 81, yellow = 50, white = 27)
chisq_test(tulip)
chisq_test(tulip, p = c(1/2, 1/3, 1/6))
df %>% chisq_test(gender, smoker)
df %>% chisq_test(vars = c("gender", "smoker"), correct = FALSE)
The reference page warns that in the positional form the second column occupies the correct argument slot, so to set correct or simulate.p.value use the vars form shown in the last call.
Troubleshooting
Error when p does not sum to 1
A goodness-of-fit call with p not summing to 1 stops with an error unless you set rescale.p = TRUE. Negative entries in p always error.
Results look wrong on raw data
If each element of x is one observation rather than a count, wrap it: chisq.test(table(x)).
The 2 x 2 result changes between software
R applies a continuity correction to 2 x 2 tables by default. Set correct = FALSE to match software or textbook formulas that do not correct; see continuity corrections.
Small expected counts
Inspect res$expected. If cells are small, compare the asymptotic result with simulate.p.value = TRUE and with fisher.test() as described above. The manual’s example comment on a table with an expected count of 1.86 calls it “maybe doubtful, but is ok!”, a reminder that the judgement is the analyst’s.
The simulation is slow
The manual says the goodness-of-fit simulation may be slow; lower B for exploration and raise it for the final result.
Free alternatives
| Function | Package | Use it when |
|---|---|---|
chisq.test() |
stats (base R) | Goodness of fit or independence, with matrix, vector or factor input. |
chisq_test() |
rstatix (CRAN) | You want a data frame result and a pipe-friendly vars interface. |
fisher.test() |
stats (base R) | Independence with fixed marginals, where the chi-squared approximation is in doubt; simulation is available for tables larger than 2 x 2. |
For the same test in another package, see chi-square test in Stata.
FAQ
How do I run a chi-square test in R?
Call chisq.test() on a vector of counts for goodness of fit, or on a matrix (or two factors) for independence. It is part of base R, so no package is needed.
Is a chi squared test in R the same as a chi-square test in R?
Yes. Both spellings refer to chisq.test(); “chi-squared” and “chi-square” are used interchangeably.
How do I get the expected counts?
Save the result and read $expected: res <- chisq.test(tab); res$expected.
How do I turn off the Yates continuity correction?
Set correct = FALSE. The correction applies only to 2 x 2 tables.
What do I use when expected counts are small?
Use simulate.p.value = TRUE or fisher.test(), both described in the R manual.
Sources (official docs)
- R Core Team, stats::chisq.test reference page, checked 2026-10-29.
- R Core Team, stats::fisher.test reference page, checked 2026-10-29.
- rstatix reference, chisq_test(), checked 2026-10-29.








