Identify outliers in chi-squared goodness of fit test I am performing a chi-square goodness of fit test to compare an observed value with an expected value. The expected value is calculated from theory. p-value suggests statistical significance. How do I find out which cells contribute the most to the chi-square and what would be the best way to illustrate this graphically. I calculated the standardized residuals (observed-expected)/sqrt(expected). How do choose outliers in the plot? The real data is below.




Motif
Observed
Predicted




QGP
1365
1100


KGP
1295
1280


TGP
1179
1141


KGD
774
611


PGP
746
649


QGE
616
388


TGA
605
298


TGD
584
545


KGL
518
257


PGD
500
310


RGP
451
333


PGE
394
229


SGS
366
95


KGI
365
192


DGA
362
93


QGI
325
165


KGE
290
452


TGS
264
246


AGP
260
260


QGD
246
525


DGT
236
59


SGD
232
211


IGE
212
73


QGL
207
221


TGL
181
229


SGP
180
442


SGT
171
74


KGS
169
276


IGP
166
206




It's possible that the chi-square test is not giving you the information you want.
A simple way to compare observed and expected is to plot the two variables and superimpose a 1:1 line.  This gives you some sense if there is a systematic difference in the results, and lets you visually identify those observation that are far from this 1:1 line.
In addition, a Bland-Altman plot may be more useful for this purpose. Image, Wikipedia
From the data you posted, the observed values are somewhat systematically larger than the predicted values.  This is shown by the number of data points above and to the left of the 1:1 line.
Some R code follows.


Data=read.table(header=TRUE, stringsAsFactors=TRUE, text="
motif    observed    predicted
QGP       1365       1100 
KGP       1295       1280 
TGP       1179       1141 
KGD        774        611 
PGP        746        649 
QGE        616        388 
TGA        605        298 
TGD        584        545 
KGL        518        257 
PGD        500        310 
RGP        451        333 
PGE        394        229 
SGS        366         95 
KGI        365        192 
DGA        362         93 
QGI        325        165 
KGE        290        452 
TGS        264        246 
AGP        260        260 
QGD        246        525 
DGT        236         59 
SGD        232        211 
IGE        212         73 
QGL        207        221 
TGL        181        229 
SGP        180        442 
SGT        171         74 
KGS        169        276 
IGP        166        206
")

plot(observed ~ predicted, data=Data)
abline(0,1, col="blue")

wilcox.test(Data$observed, Data$predicted, paired=TRUE)

Group = factor(
          c(rep("Predicted", length(Data$predicted)),
          rep("Observed", length(Data$observed))))

Response = c(Data$predicted, Data$observed)

plot(Response ~ Group)

library(FSA)

Summarize(Response ~ Group)

library(rcompanion)

efronRSquared(actual= Data$observed, predicted=Data$predicted, statistic="RMSE")

EDIT: Some additional code to examine differences:
Data$Diff = (Data$observed - Data$predicted)

hist(Data$Diff)

head(Data[order(Data$Diff),], n=10L)

head(Data[order(-Data$Diff),], n=10L)

EDIT 2: Some additional code to examine z-scores of differences
library(rcompanion)

Data$ZScore = blom(Data$Diff, method="zscore")

head(Data[order(Data$ZScore),], n=10L)

head(Data[order(-Data$ZScore),], n=10L)

Edit 3: Chi-square goodness-fit-test and standardized residuals
Data$prop = Data$predicted/sum(Data$predicted)

chisq.test(Data$observed, p=Data$prop)

Data$stdres = chisq.test(Data$observed, p=Data$prop)$stdres

head(Data[order(Data$stdres),], n=10L)

head(Data[order(-Data$stdres),], n=10L)

plot(Diff ~ stdres, data = Data)

summary(Data)

