Home › Research Methodology › Chi-Square Test Explained
Below, we explain the chi-square test step by step and run it live on real data from ScholarsColab.
Chi-square test at a glance
| Item | Plain meaning |
|---|---|
| Used for | Two categorical variables, such as gender and course choice |
| Data | Counts in a table (a contingency table) |
| Null hypothesis | The two variables are independent (not related) |
| Observed counts | What actually happened |
| Expected counts | What would happen if there were no relationship |
| Result | χ² value, degrees of freedom and p-value; Cramér’s V for strength |
Worked example: do research fields prefer journals or conferences?
We run a complete chi-square test, notebook-style, on real publication data. Every result is calculated live, and you can run the same code yourself.
The data: 41,792 papers, mostly published between 1998 and 2026, by 967 ScholarsColab mentors (data updated 15 October 2026). The file you will load is anonymised: no paper titles, journal names or researcher identities.
Step 1: Load the data
import numpy as np
import pandas as pd
from datetime import date
# The ScholarsColab Research Methods Index (papers level): anonymised, updated daily
DATA = "https://scholarscolab.com/wp-json/scholarscolab/v1/research-methods-data?level=papers"
papers = pd.read_csv(DATA, comment="#") # lines starting with # hold the citation
def p_text(p):
return "< 0.001" if p < 0.001 else f"= {p:.3f}"
print(papers.shape)
papers.head()(41792, 15)
| year | citations | venue_type | venue_group | title_words | title_colon | review | systematic | machine_learning | deep_learning | iot | blockchain | covid | sustainability | discipline | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023.0 | 31 | journal | Other journals | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Medicine & health |
| 1 | 2024.0 | 24 | journal | Other journals | 13 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | Medicine & health |
| 2 | 2024.0 | 12 | journal | Other journals | 16 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Medicine & health |
| 3 | 2024.0 | 9 | journal | Other journals | 20 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Medicine & health |
| 4 | 2024.0 | 9 | journal | Generic "International Journal of" | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Medicine & health |
Step 2: Build the contingency table
Our two categorical variables are the research discipline and the type of venue (journal or conference). A contingency table counts the papers in every combination.
jc = papers[papers["venue_type"].isin(["journal", "conference"])]
table = pd.crosstab(jc["discipline"], jc["venue_type"])
table| conference | journal | |
|---|---|---|
| Engineering & computer science | 5943 | 12841 |
| Life & environmental sciences | 235 | 4298 |
| Management, economics & finance | 197 | 1750 |
| Medicine & health | 751 | 5194 |
| Other or unclassified | 448 | 2425 |
| Physical sciences & mathematics | 189 | 2454 |
| Social sciences & education | 40 | 592 |
Step 3: Run the test and compare observed with expected counts
The test asks: if discipline and venue type were unrelated, how many papers would we expect in each cell? Those expected counts are shown below the result.
from scipy import stats
chi2, p, dof, expected = stats.chi2_contingency(table)
n = table.to_numpy().sum()
cramers_v = np.sqrt(chi2 / (n * (min(table.shape) - 1)))
print(f"chi2 = {chi2:.1f}, df = {dof}, p {p_text(p)}, Cramér's V = {cramers_v:.2f}")
pd.DataFrame(expected, index=table.index, columns=table.columns).round(0)chi2 = 2803.7, df = 6, p < 0.001, Cramér's V = 0.27
| conference | journal | |
|---|---|---|
| Engineering & computer science | 3924.0 | 14860.0 |
| Life & environmental sciences | 947.0 | 3586.0 |
| Management, economics & finance | 407.0 | 1540.0 |
| Medicine & health | 1242.0 | 4703.0 |
| Other or unclassified | 600.0 | 2273.0 |
| Physical sciences & mathematics | 552.0 | 2091.0 |
| Social sciences & education | 132.0 | 500.0 |
Step 4: Show the pattern in a chart
import matplotlib.pyplot as plt
share = (table["conference"] / table.sum(axis=1) * 100).sort_values()
overall = table["conference"].sum() / n * 100
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(share.index, share.values, color="lightgreen", edgecolor="green")
ax.axvline(overall, color="green", linestyle="--", label=f"All disciplines: {overall:.1f}%")
ax.set_xlabel("% of papers published at conferences")
ax.legend()
plt.tight_layout()
plt.show()Types of chi-square test
| Test | Question | Example |
|---|---|---|
| Test of independence | Are two categorical variables related? | Is discipline related to using machine learning? |
| Goodness-of-fit test | Does one variable match an expected distribution? | Are births equally spread across the days of the week? |
How to run a chi-square test
- Arrange the counts in a table with one variable in rows and the other in columns.
- Check the assumptions: counts (not percentages), independent observations, and expected counts of at least 5 in most cells.
- Run the test in SPSS, R, Python or Excel (CHISQ.TEST).
- Report χ², degrees of freedom, sample size and p-value, for example, from the test above: χ²(6, N = 37,357) = 2,803.7, p < 0.001.
- Add an effect size such as Cramér’s V, and look at which cells differ most from expected.
Common mistakes reviewers point out
- Running the test on percentages instead of counts.
- Too many small expected counts; use Fisher’s exact test for small tables.
- Stopping at “significant” without saying which categories differ or how strongly.
- Counting the same person more than once.
Frequently asked questions
What does a chi-square test tell you?
It tells you whether the pattern of counts in a table differs from what you would expect if two categorical variables were unrelated.
When should I use a chi-square test?
Use it when both variables are categorical, such as yes/no or groups, and your data are counts of independent observations.
What are degrees of freedom in a chi-square test?
For a test of independence, degrees of freedom equal (number of rows − 1) × (number of columns − 1).
What is Cramér’s V?
Cramér’s V measures the strength of the relationship found by a chi-square test, from 0 (no relationship) to 1 (perfect relationship).
What if expected counts are below 5?
Combine small categories if it makes sense, or use Fisher’s exact test, which works with small counts.
Use this data in your own work
ScholarsColab (2026). ScholarsColab Research Methods Index [Data set]. Vidhilekha Soft Solutions Pvt Ltd. Retrieved 15 October 2026, from https://scholarscolab.com/research-methodology/. Licensed under CC BY 4.0.Download the data (CSV) →Need help applying this to your research?
Discuss your research problem with a PhD mentor, hand the whole project to a research project manager, or post your project and let matched experts apply.
Mentors whose published work uses this approach:
Rashid MenhasShandong Xiehe University, Jinan, China1 related paper · View profile →
Sancho XavierUniversity of São Paulo1 related paper · View profile →
Boon-How ChewUniversiti Putra Malaysia1 related paper · View profile →
Prof. (Dr.) Akhilesh A. WaooAKS University, SATNA, MP1 related paper · View profile →
