within the framework of an exercise, I have 2 factors: a type of animal & a database

M <- as.table(rbind(c(22000, 2300, 42009,106000), c(380,30,7,260)))
dimnames(M) <- list(Databases=c("database1","database2"), Animals=c("Bird","Dog", "Cat","Mouse"))# 

Databases     Bird    Dog    Cat  Mouse
  database1  22000   2300  42009 106000
  database2    380     30      7    260

And I would simply like to know if compared to the database1, the database2 follows the same distributions of the number of individuals per animal? For example, here we see that in the database1 there are many more Mouse (106000 or 69.6%) while in the database2 there are only 260 or 38.4%.

Does someone have an idea of what test I could use to test the difference in repartition between the 2 databases please?


2 Answers 2


By inspection, it is pretty clear that Cat is under-represented in the second database. Let's see how that plays out in a chi-squared test of your $2\times 4$ contingency matrix.

db1 =  c(22000,   2300,  42009, 106000)
db2 =  c(  380,     30,      7,    260)
MAT= rbind(db1,db2);  MAT
     [,1] [,2]  [,3]   [,4]
db1 22000 2300 42009 106000
db2   380   30     7    260


        Pearson's Chi-squared test

data:  MAT
X-squared = 1238, df = 3, p-value < 2.2e-16

The null hypothesis that the proportions are the same in the two databases is very strongly rejected with P-value near $0.$

The sum of the squares of the Pearson Residuals is the chi-squared statistic $1238.$ Residuals with the largest absolute value point the way to the cells in which the observed and expected counts differed most.

         [,1]       [,2]        [,3]       [,4]
db1 -1.958478 -0.4334418   0.7695618  0.4790736
db2 31.244842  6.9149717 -12.2773080 -7.6429657

So it's birds and cats that have the greatest differences in proportions. Ad hoc, we can look at the $2 \times 2$ contingency matrix for just birds and cats.

chisq.test(MAT[,c(1,3)], cor=F)

        Pearson's Chi-squared test

data:  MAT[, c(1, 3)]
X-squared = 690.98, df = 1, p-value < 2.2e-16

Based on your interests, you could look at other sub-matrices as well. Ordinarily, one would be concerned about false discovery, doing multiple tests on the same data, but with P-values as small as this, one can do several ad hoc tests without using methods such as Bonferroni's to adjust significance levels.

Addendum per question in Comment. Suppose we had

Db1 =  c(22000,   2300,  42009, 106000)
Db2 =  c(  380,     30,      4,    260)
MTR = rbind(Db1,Db2);  MTR

The chi-squared test works OK with the smaller cell you proposed. Maybe you have read about needing counts to be above $5.$ That's for 'expected counts' computed from row and column totals, based on $H_0.$ The counts in MTR are 'observed counts'. In R you can look at expected counts using $-notation:

chisq.test(MTR, cor=F)$exp
           [,1]        [,2]       [,3]        [,4]
Db1 22292.79999 2320.921536 41849.3032 105845.9753
Db2    87.20001    9.078464   163.6968    414.0247

Because of relatively large row and column totals, cell [2,3] is OK (along with all the others). If not, chisq.test would show a warning message in output, saying that the P-value may not be accurate. Then you could use parameter sim=T in chisq.test to simulate a more useful P-value.

chisq.test(MTR, cor=F)

        Pearson's Chi-squared test

data:  MTR
X-squared = 1249.3, df = 3, p-value < 2.2e-16

> chisq.test(MTR, cor=F)$exp
           [,1]        [,2]       [,3]        [,4]
Db1 22292.79999 2320.921536 41849.3032 105845.9753
Db2    87.20001    9.078464   163.6968    414.0247
  • 1
    $\begingroup$ Wow thank you very much for all the details. I also had another one, what if now istead of 7 for ```database2-Cat`` I had 4. Could I still use this approach? $\endgroup$ Commented Jun 15, 2021 at 8:16
  • $\begingroup$ I see why you're asking that. See Addendum to my Answer for this proposed change. $\endgroup$
    – BruceET
    Commented Jun 16, 2021 at 15:17

A $\chi^2$-test would be the obvious choice, especially since you do not seem to have a problem with small cell counts.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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