# Classification table for ordinal logistic regression in R

I want to create a classification table regarding an ordinal response variable with three levels but I don't know how to do it. Searching on the site I fell on the question posted by Brandon Bertelsen that covers only the case of the binary logistic regression (link at the end of the post).Does anyone knows how I can create such that table in my case?

I don't know if it is important but I used the rms package to run the olr and using the predict(fit,type="fitted.ind") command I get the next table with probability for each case

      grade=1    grade=2   grade=3
1  0.08042197 0.28380601 0.6357720
2  0.08086877 0.28475584 0.6343754
3  0.41472656 0.40802584 0.1772476
4  0.39680650 0.41484517 0.1883483
5  0.25402385 0.43644283 0.3095333
6  0.13539881 0.37098177 0.4936194
7  0.12591996 0.35959459 0.5144855
8  0.50489952 0.36489760 0.1302029
9          NA         NA        NA
10 0.34757283 0.42969971 0.2227275
11 0.24690054 0.43539812 0.3177013
12 0.17325212 0.40529586 0.4214520
13 0.45795712 0.38900855 0.1530343
14 0.03594015 0.16033637 0.8037235
15         NA         NA        NA
16 0.50188652 0.36653955 0.1315739
17 0.48710163 0.37441720 0.1384812
18 0.38094725 0.42028884 0.1987639
19 0.04134659 0.17894428 0.7797091
20 0.12844729 0.36275605 0.5087967
21 0.23991274 0.43410413 0.3259831
22 0.20506362 0.42316514 0.3717712
23 0.45457929 0.39061326 0.1548075
24         NA         NA        NA
25 0.31269786 0.43606610 0.2512360
26 0.20905830 0.42483513 0.3661066
27 0.05240710 0.21353381 0.7340591
28 0.26569967 0.43759072 0.2967096
29 0.21258621 0.42621415 0.3611996
30 0.11407246 0.34347156 0.5424560
31 0.34656138 0.42993750 0.2235011
32 0.01813256 0.08978609 0.8920813
33 0.44034224 0.39716470 0.1624931
34 0.12213714 0.35468488 0.5231780
35 0.40888783 0.41032190 0.1807903
36 0.33901842 0.43161582 0.2293658
37 0.13275554 0.36793345 0.4993110
38 0.32091057 0.43492411 0.2441653
39 0.45984161 0.38810515 0.1520532
40 0.55550665 0.33564053 0.1088528
41 0.02812293 0.13122652 0.8406505
42 0.46250424 0.38681892 0.1506768
43 0.07352751 0.26852580 0.6579467
44 0.04330967 0.18541327 0.7712771
45 0.45457929 0.39061326 0.1548075


Logistic Regression: Classification Tables a la SPSS in R

-
 It's not entirely clear to me what you're asking for. How does what you want differ from the table you reproduce above? – gung Apr 10 '12 at 16:38 I am sorry if I didn't make my self clear. I want to make a classification 3x3 table similar to the link I posted at the end (classification table a la SPSS in R). I posted the probability table just to show the result I take when I run the olr and in case it might help anyone – Nick Apr 10 '12 at 16:57

If you really want to use the predicted group membership probabilities to compare actual vs. predicted group memberships (despite the recommendation given in the answer to this question), you could just modify the answer to the linked question like this:

# generate some data
N <- 100
X <- rnorm(N, 175, 7)
Y <- 0.4*X + 10 + rnorm(N, 0, 3)

# categorize Y (three groups of about equal size)
Yfac <- cut(Y, quantile(Y, probs=seq(0, 1, length=4)),
include.lowest=TRUE, labels=c("lo", "mid", "hi"))

# ordinal logistic regression
library(rms)                  # for lrm()
fit <- lrm(Yfac ~ X)

# predicted group membership probabilities
YhatP <- predict(fit, type="fitted.ind")

# group membership prediction: choose group with maximum probability
YhatFac <- levels(Yfac)[max.col(YhatP)]

# (3x3)-contingency table actual vs. predicted group memberships
cTab <- table(Yfac, YhatFac)


Now add the marginal frequencies and calculate percentage correct for the training data.

> addmargins(cTab)
YhatFac
Yfac   hi  lo mid Sum
lo    6  20   8  34
mid   9   6  18  33
hi   19   4  10  33
Sum  34  30  36 100

# percentage correct for training data
> sum(diag(cTab)) / sum(cTab)
[1] 0.22

-
 Thanks a lot. Although at the end it seems inappropriate to use it, I'll definitely keep the code you wrote. – Nick Apr 11 '12 at 12:47

I gather you want to cross-tabulate the grade predicted by the model with the actual grade (correct me if that's not right). Since cross-tabulation is pretty simple, presumably the real question is how to extract a predicted category (i.e., grade) from the model (i.e., the probability table you pasted into the question above). As it happens, I asked a similar question a while back. Although it may seem unsatisfying, the answer appears to be that you just don't convert the predicted probabilities into predicted categories. Once you've gotten the predicted probabilities, you're done.

Update: What SPSS does, if I recall correctly, is simply assign each observation to whichever category is associated with the largest predicted probability. You can certainly do that in R, using max.col(), e.g.:

x = data.frame(cat1=c(.1,.3,.2), cat2=c(.3,.2,.1), cat3=c(.6,.5,.7))
x
cat1 cat2 cat3
1  0.1  0.3  0.6
2  0.3  0.2  0.5
3  0.2  0.1  0.7
predCats = colnames(x)[max.col(x)]
predCats
[1] "cat3" "cat3" "cat3"


The question is whether this is really the right way to think about your data. As I mentioned in my question, this leads to mediocre predictive accuracy that is below the concordance.

-
 That's exactly what I want to do, but it seems that it's not possible. But if I run the olr in SPSS I get that 3x3 table and so I believed there could be a way to create it in R like in the binary logistic regression. – Nick Apr 10 '12 at 17:48 Thanks for the answer. To be honest I didn't check your answer yesterday because I had to leave. Could you please explain to me how you calculated the "accuracy is 57%" in your question? – Nick Apr 11 '12 at 12:41 That value was specific to that dataset. If you cross-tabulate the actual category vs. the one predicted by this (or really any) method, you sum the counts on the diagonal & divide by the total & that gives the % correct. @caracal's code walks you through this procedure: table(), sum(diag())/sum(); (nb, addmargins() isn't strictly necessary, it just makes the table more intelligible). – gung Apr 11 '12 at 13:06 Ok I got it. Thanks again – Nick Apr 11 '12 at 13:19 If you feel like the question has been addressed satisfactorily at this point, you may want to accept one of them by clicking the check mark next to it. – gung Apr 11 '12 at 14:02