-
Notifications
You must be signed in to change notification settings - Fork 0
/
103_ologit.Rmd
80 lines (51 loc) · 1.44 KB
/
103_ologit.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Ordered Logit
<!-- Discussion of the model goes here -->
```{r}
inv_logit <- function(x) {
p <- 1 / (1 + exp(-x))
return(p)
}
ologit <- function(data, formula, na.action=na.exclude) {
mf <- model.frame(formula, data, na.action=na.exclude)
Y <- model.response(mf)
X <- model.matrix(formula, mf)[,-1]
N <- nrow(X)
levels <- unique(Y) |> sort()
M <- length(levels)
ncut <- M-1
c <- 1:ncut/M
b <- numeric(ncol(X))
par <- c(c,b)
ologitLL <- function(param) {
c <- param[1:ncut]
b <- param[(ncut+1):length(param)]
Xb <- X %*% b
lli <- numeric(N)
for (m in 1:M) {
if (m == 1) {
lli[Y==levels[m]] <- log(inv_logit(c[m]-Xb[Y==levels[m]]))
} else if (m < M) {
lli[Y==levels[m]] <- log(inv_logit(c[m]-Xb[Y==levels[m]]) - inv_logit(c[m-1]-Xb[Y==levels[m]]))
} else {
lli[Y==levels[m]] <- log(1 - inv_logit(c[m-1]-Xb[Y==levels[m]]))
}
}
return(-sum(lli))
}
out <- optim(par, ologitLL, method="BFGS")
est <- out$par
names(est)[1:ncut] <- paste0("t", 1:ncut)
names(est)[(ncut+1):length(est)] <- colnames(X)
return(est)
}
```
Testing the function:
```{r}
# Example from https://towardsdatascience.com/implementing-and-interpreting-ordinal-logistic-regression-1ee699274cf5
library(carData)
library(MASS)
data(WVS)
f <- poverty~religion+degree+country+age+gender
summary(polr(f, WVS))
ologit(WVS, f)
```