-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathpoiszeroinfl.R
93 lines (71 loc) · 2.47 KB
/
poiszeroinfl.R
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
81
82
83
84
85
86
87
88
89
90
91
92
93
#' ---
#' title: "Zero-inflated Poisson Model"
#' author: "Michael Clark"
#' date: ""
#' ---
#'
#' Log likelihood function to estimate parameters for a Zero-inflated Poisson model. With examples
#' and comparison to pscl package output. Also includes approach based on Hilbe GLM text.
#' see also: https://github.com./m-clark/Miscellaneous-R-Code/blob/master/ModelFitting/NBzeroinfl.R
ZIP = function(y, X, par) {
# arguments are response y, predictor matrix X, and parameter named starting points of 'logit' and 'pois'
# Extract parameters
logitpars = par[grep('logit', names(par))]
poispars = par[grep('pois', names(par))]
# Logit part; in this function Xlogit = Xpois but one could split X argument into Xlogi and Xpois for example
Xlogit = X
LPlogit = Xlogit %*% logitpars
logi0 = plogis(LPlogit) # alternative 1/(1+exp(-LPlogit))
# Poisson part
Xpois = X
mupois = exp(Xpois %*% poispars)
# LLs
logliklogit = log( logi0 + exp(log(1 - logi0) - mupois) )
loglikpois = log(1 - logi0) + dpois(y, lambda = mupois, log = TRUE)
# Hilbe formulation
# logliklogit = log(logi0 + (1 - logi0)*exp(- mupois) )
# loglikpois = log(1-logi0) -mupois + log(mupois)*y #not necessary: - log(gamma(y+1))
y0 = y == 0 # 0 values
yc = y > 0 # Count part
loglik = sum(logliklogit[y0]) + sum(loglikpois[yc])
-loglik
}
#' Get the data
library(haven)
library(pscl)
fish = read_dta("http://www.stata-press.com/data/r11/fish.dta")
#' Get starting values or simply do zeros
#' for this function, a named vector for the starting values
#' for zip: need 'logit', 'pois'
init.mod = glm(
count ~ persons + livebait,
data = fish,
x = TRUE,
y = TRUE,
"poisson"
)
# starts = c(logit = coef(init.mod), pois = coef(init.mod))
starts = c(rep(0, 3), rep(0, 3))
names(starts) = c(paste0('pois.', names(coef(init.mod))),
paste0('logit.', names(coef(init.mod))))
#' Estimate with optim function
optPois1 = optim(
par = starts ,
fn = ZIP,
X = init.mod$x,
y = init.mod$y,
method = "BFGS",
control = list(maxit = 5000, reltol = 1e-12),
hessian = TRUE
)
# optPois1
#' Comparison
# Extract for clean display
B = optPois1$par
se = sqrt(diag(solve((optPois1$hessian))))
Z = B/se
p = pnorm(abs(Z), lower = FALSE)*2
# pscl results
zipoismod = zeroinfl(count ~ persons + livebait, data = fish, dist = "poisson")
summary(zipoismod)
round(data.frame(B, se, Z, p), 4)