What is H0 for the Chi-squared Test of Independence?

I know, it sounds like a very easy question but check this out.

According to R Tutorial (link below), from the answer of the first problem, it implies that:

H0: A is independent from B

Ha: A is dependent to B

where A and B are to variables,

From the way hypothesis testing works with alpha = .05:

For p-value > .05 ; H0 is plausible (or true)

For p-value =< .05 ; H0 is rejected

Nothing mindblowing or new so far...

Until I tried to test it in R...

I create 2 data frames:

df1 with two perfectly linearly dependent variables,

df2 with two very linearly independent variables,

To give some context, I am comparing the number of hours spent studying vs the grade obtained.

df1<- data.frame("Hours_Studied" = c(10,5,2,9),

df2<- data.frame("Hours_Studied" = c(10,5,2,9),
            "Grade"=sample(c(0:100), 4))

When I run this code, this is what I get:

For df1 I get p-value = 1 which means that H0 is plausible (or true) therefore H0: A is independent to B. BUT this is not the case!

For df2 I get p-value = 1.914e-06 which means that H0 is rejected therefore Ha: A is dependent to B. BUT this is not the case!

Am I missing something extremely obvious? Am I going crazy? Why does this simple example give the opposite results?

Thank you in advance,

I sincerely hope that you and your loved one are well and safe during this pandemic.

link to R Tutorial: http://www.r-tutor.com/elementary-statistics/goodness-fit/chi-squared-test-independence

  • $\begingroup$ Not sure why exactly this is happening but in your example the variables are perfectly dependent. See here df1<- data.frame("Hours_Studied" = rep(c(10,5,2,9), 100)) df1$Grade <- 100 + df1$Hours_Studied +round(rnorm(nrow(df1), 10,.5), 0) plot(df1) chisq.test(df1) $\endgroup$
    – user248711
    May 10, 2020 at 18:34
  • $\begingroup$ Row / columns independence and linear relationships are two different things. Chi-square , fisher etc, you start with two categorical variables and you want to test whether the classes in these are independent, and you construct a contingency table from that to give you the counts $\endgroup$
    – StupidWolf
    May 10, 2020 at 18:43
  • $\begingroup$ you can read here for more biostathandbook.com/fishers.html. And I am afraid this is more suited for cross-validated or self study.. $\endgroup$
    – StupidWolf
    May 10, 2020 at 18:46

1 Answer 1


The chi square test chisq.test() evaluates whether the observed values in a two way contingency table are significantly different from their expected values.

In the case of the posted question, the contingency table evaluated by the test looks like this, where the column dimension represents the columns from the data frame, and the row dimension of the contingency table is represented by the rows in the data frame.

> result$observed
     Hours_Studied Grade
[1,]            10   100
[2,]             5    50
[3,]             2    20
[4,]             9    90

The expected values for each cell in this contingency table are calculated as the frequencies of the row marginal times the column marginal divided by the total frequency.

In R, we can calculate this as follows:

rowsum <- rowSums(df1)
colsum <- colSums(df1)
total <- sum(rowsum)
expected <- matrix(nrow = 4,ncol = 2)
for(i in 1:length(rowsum)){
     for(j in 1:length(colsum)) expected[i,j] <- rowsum[i] * colsum[j] / total 

...and the output is:

> expected
     [,1] [,2]
[1,]   10  100
[2,]    5   50
[3,]    2   20
[4,]    9   90

The print confirms that the expected values equal the actual values, so the sum of the squared differences will be zero, and therefore chi squared will be equal to zero.

The degrees of freedom for a chi square on a contingency table are calculated as:

 (rows - 1) * (columns - 1)
 (2 - 1) * (4 - 1) 

Therefore, we have a chi square of 0 with 3 degrees of freedom, and the associated probability value is 1.0, calculated in R as follows.

> pchisq(0,3,lower.tail = FALSE)
[1] 1

While the columns in the original data frame are perfectly linearly correlated, when analyzed as a contingency table as cell frequencies instead of interval / ratio data, there is no association between the rows and columns.

  • $\begingroup$ I think you're wrong: the table is found as as.matrix(df1), not as table(df1). The rows of the data frame are one variable, the columns the other. $\endgroup$ May 10, 2020 at 19:31
  • $\begingroup$ @user2554330 - thanks for the feedback. Updated answer includes manual calculations to illustrate that the data in the table is equal to marginal distributions of the input 4x2 contingency table, which leads to a chi square of 0. $\endgroup$
    – Len Greski
    May 10, 2020 at 21:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.