Skip to main content
v2026.11,858 entries · CC-BY 4.0

Chi-Square Test in R: chisq.test() Arguments, Output and Small-Count Options

How to run a chi-squared test in R with chisq.test(): arguments by mode, what the output holds, and simulate.p.value or fisher.test() for small counts.

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

  1. Put the observed counts in a numeric vector, for example counts <- c(81, 50, 27).
  2. If you expect equal proportions, call chisq.test(counts). When p is omitted, all categories are expected to be equally likely.
  3. If you expect other proportions, pass them in p, one per element of x: chisq.test(counts, p = c(1/2, 1/3, 1/6)).
  4. If your p values are relative weights that do not sum to 1, add rescale.p = TRUE. The manual states that with rescale.p = FALSE, a p that does not sum to 1 gives an error, and negative entries in p also give an error.

Chi-squared test of independence in R

  1. From a table of counts, build a matrix: tab <- matrix(c(12, 5, 7, 7), ncol = 2), then call chisq.test(tab).
  2. From two columns of raw data, pass them as x and y: chisq.test(df$gender, df$smoker), or cross-tabulate first with table(); see crosstabs in R.
  3. For a 2 x 2 table R applies a continuity correction by default (correct = TRUE). To turn it off, use correct = 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 = TRUE computes 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 size sum(x) from p; 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 own simulate.p.value option, 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. Its hybrid = TRUE option uses the chi-squared approximation only when Cochran’s conditions are met (defaults in hybridPars: 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)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Chi-Square Test in R: chisq.test() Arguments, Output and Small-Count Options

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.