FreddyHernandez commited on
Commit
19bc544
verified
1 Parent(s): 8a5be2b

Upload 6 files

Browse files
Files changed (6) hide show
  1. ExWALD.R +307 -0
  2. WALD.R +131 -0
  3. dExWALD.R +192 -0
  4. dWALD.R +116 -0
  5. server.R +137 -0
  6. ui.R +38 -0
ExWALD.R ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #' The Ex-Wald family
2
+ #'
3
+ #' @author Freddy Hernandez, \email{fhernanb@unal.edu.co}
4
+ #'
5
+ #' @description
6
+ #' The function \code{ExWALD()} defines the Ex-wALD distribution, three-parameter
7
+ #' continuous distribution for a \code{gamlss.family} object to be used in
8
+ #' GAMLSS fitting using the function \code{gamlss()}.
9
+ #'
10
+ #' @param mu.link defines the mu.link, with "log" link as the default for the mu parameter.
11
+ #' @param sigma.link defines the sigma.link, with "log" link as the default for the sigma parameter.
12
+ #' @param nu.link defines the nu.link, with "log" link as the default for the nu parameter.
13
+ #'
14
+ #' @references
15
+ #' Schwarz, W. (2001). The ex-Wald distribution as a descriptive model
16
+ #' of response times. Behavior Research Methods,
17
+ #' Instruments, & Computers, 33, 457-469.
18
+ #'
19
+ #' Heathcote, A. (2004). Fitting Wald and ex-Wald distributions to
20
+ #' response time data: An example using functions for the S-PLUS package.
21
+ #' Behavior Research Methods, Instruments, & Computers, 36, 678-694.
22
+ #'
23
+ #' @seealso \link{dExWALD}.
24
+ #'
25
+ #' @details
26
+ #' The Ex-Wald distribution with parameters \eqn{\mu}, \eqn{\sigma}
27
+ #' and \eqn{\nu} has density given by
28
+ #'
29
+ #' \eqn{f(x |\mu, \sigma, \nu) = \frac{1}{\nu} \exp(\frac{-x}{\nu} + \sigma(\mu-k)) F_W(x|k, \sigma) \, \text{for} \, k \geq 0}
30
+ #'
31
+ #' \eqn{f(x |\mu, \sigma, \nu) = \frac{1}{\nu} \exp\left( \frac{-(\sigma-\mu)^2}{2x} \right) Re \left( w(k^\prime \sqrt{x/2} + \frac{\sigma i}{\sqrt{2x}}) \right) \, \text{for} \, k < 0}
32
+ #'
33
+ #' where \eqn{k=\sqrt{\mu^2-\frac{2}{\nu}}},
34
+ #' \eqn{k^\prime=\sqrt{\frac{2}{\nu}-\mu^2}} and
35
+ #' \eqn{F_W} corresponds to the cumulative function of
36
+ #' the Wald distribution.
37
+ #'
38
+ #' More details about those expressions
39
+ #' can be found on page 680 from Heathcote (2004).
40
+ #'
41
+ #' @returns Returns a gamlss.family object which can be used to fit a
42
+ #' Ex-WALD distribution in the \code{gamlss()} function.
43
+ #'
44
+ #' @example examples/examples_ExWALD.R
45
+ #'
46
+ #' @importFrom gamlss.dist checklink
47
+ #' @importFrom gamlss rqres.plot
48
+ #' @export
49
+ ExWALD <- function(mu.link="log",
50
+ sigma.link="log",
51
+ nu.link="log") {
52
+
53
+ mstats <- checklink("mu.link", "Ex-Wald",
54
+ substitute(mu.link), c("log"))
55
+ dstats <- checklink("sigma.link", "Ex-Wald",
56
+ substitute(sigma.link), c("log"))
57
+ vstats <- checklink("nu.link", "Ex-Wald",
58
+ substitute(nu.link), c("log"))
59
+
60
+ structure(list(family = c("ExWALD", "Ex-Wald"),
61
+ parameters = list(mu=TRUE, sigma=TRUE, nu=TRUE),
62
+ nopar = 3,
63
+ type = "Continuous",
64
+
65
+ mu.link = as.character(substitute(mu.link)),
66
+ sigma.link = as.character(substitute(sigma.link)),
67
+ nu.link = as.character(substitute(nu.link)),
68
+
69
+ mu.linkfun = mstats$linkfun,
70
+ sigma.linkfun = dstats$linkfun,
71
+ nu.linkfun = vstats$linkfun,
72
+
73
+ mu.linkinv = mstats$linkinv,
74
+ sigma.linkinv = dstats$linkinv,
75
+ nu.linkinv = vstats$linkinv,
76
+
77
+ mu.dr = mstats$mu.eta,
78
+ sigma.dr = dstats$mu.eta,
79
+ nu.dr = vstats$mu.eta,
80
+
81
+ # First derivates
82
+
83
+ dldm = function(y, mu, sigma, nu) {
84
+ dm <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
85
+ theta="mu",
86
+ delta=0.001)
87
+ dldm <- as.vector(attr(dm, "gradient"))
88
+ dldm
89
+ },
90
+
91
+ dldd = function(y, mu, sigma, nu) {
92
+ dd <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
93
+ theta="sigma",
94
+ delta=0.001)
95
+ dldd <- as.vector(attr(dd, "gradient"))
96
+ dldd
97
+ },
98
+
99
+ dldv = function(y, mu, sigma, nu) {
100
+ dv <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
101
+ theta="nu",
102
+ delta=0.001)
103
+ dldv <- as.vector(attr(dv, "gradient"))
104
+ dldv
105
+ },
106
+
107
+ # Second derivates
108
+
109
+ d2ldm2 = function(y, mu, sigma, nu) {
110
+ dm <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
111
+ theta="mu",
112
+ delta=0.001)
113
+ dldm <- as.vector(attr(dm, "gradient"))
114
+ d2ldm2 <- - dldm*dldm
115
+ d2ldm2 <- ifelse(d2ldm2 < -1e-15, d2ldm2, -1e-15)
116
+ d2ldm2
117
+ },
118
+
119
+ d2ldmdd = function(y, mu, sigma, nu) {
120
+ dm <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
121
+ theta="mu",
122
+ delta=0.001)
123
+ dldm <- as.vector(attr(dm, "gradient"))
124
+ dd <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
125
+ theta="sigma",
126
+ delta=0.001)
127
+ dldd <- as.vector(attr(dd, "gradient"))
128
+ d2ldmdd <- - dldm*dldd
129
+ d2ldmdd <- ifelse(d2ldmdd < -1e-15, d2ldmdd, -1e-15)
130
+ d2ldmdd
131
+ },
132
+
133
+ d2ldmdv = function(y, mu, sigma, nu) {
134
+ dm <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
135
+ theta="mu",
136
+ delta=0.001)
137
+ dldm <- as.vector(attr(dm, "gradient"))
138
+ dv <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
139
+ theta="nu",
140
+ delta=0.001)
141
+ dldv <- as.vector(attr(dv, "gradient"))
142
+ d2ldmdv <- - dldm*dldv
143
+ d2ldmdv <- ifelse(d2ldmdv < -1e-15, d2ldmdv, -1e-15)
144
+ d2ldmdv
145
+ },
146
+
147
+ d2ldd2 = function(y, mu, sigma, nu) {
148
+ dd <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
149
+ theta="sigma",
150
+ delta=0.001)
151
+ dldd <- as.vector(attr(dd, "gradient"))
152
+ d2ldd2 <- - dldd*dldd
153
+ d2ldd2 <- ifelse(d2ldd2 < -1e-15, d2ldd2, -1e-15)
154
+ d2ldd2
155
+ },
156
+
157
+ d2ldddv = function(y, mu, sigma, nu) {
158
+ dd <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
159
+ theta="sigma",
160
+ delta=0.001)
161
+ dldd <- as.vector(attr(dd, "gradient"))
162
+ dv <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
163
+ theta="nu",
164
+ delta=0.001)
165
+ dldv <- as.vector(attr(dv, "gradient"))
166
+ d2ldddv <- - dldd*dldv
167
+ d2ldddv <- ifelse(d2ldddv < -1e-15, d2ldddv, -1e-15)
168
+ d2ldddv
169
+ },
170
+
171
+ d2ldv2 = function(y, mu, sigma, nu) {
172
+ dv <- gamlss::numeric.deriv(dExWALD(y, mu, sigma, nu, log=TRUE),
173
+ theta="nu",
174
+ delta=0.001)
175
+ dldv <- as.vector(attr(dv, "gradient"))
176
+ d2ldv2 <- - dldv*dldv
177
+ d2ldv2 <- ifelse(d2ldv2 < -1e-15, d2ldv2, -1e-15)
178
+ d2ldv2
179
+ },
180
+
181
+ G.dev.incr = function(y, mu, sigma, nu, ...) -2*dExWALD(y, mu, sigma, nu, log=TRUE),
182
+ rqres = expression(rqres(pfun="pExWALD", type="Continuous", y=y, mu=mu, sigma=sigma, nu=nu)),
183
+
184
+ mu.initial = expression(mu <- rep(fitexw(y)[1], length(y))),
185
+ sigma.initial = expression(sigma <- rep(fitexw(y)[2], length(y))),
186
+ nu.initial = expression(nu <- rep(fitexw(y)[3], length(y))),
187
+
188
+ mu.valid = function(mu) all(mu > 0),
189
+ sigma.valid = function(sigma) all(sigma > 0),
190
+ nu.valid = function(nu) all(nu > 0),
191
+
192
+ y.valid = function(y) all(y > 0),
193
+
194
+ mean = function(mu, sigma, nu) {nu + sigma/mu},
195
+ variance = function(mu, sigma, nu) {nu^2 + sigma/mu^3}
196
+ ),
197
+ class = c("gamlss.family", "family"))
198
+ }
199
+ #' Auxiliar function for the Ex-Wald distribution
200
+ #' @description This function generates start values.
201
+ #' @param x a value for x.
202
+ #' @param p a value for p.
203
+ #' @return returns a vector with starting values.
204
+ #' @keywords internal
205
+ #' @importFrom stats sd var
206
+ #' @export
207
+ exwstpt <- function(x, p=0.5) {
208
+ t <- p*sd(x)
209
+ m <- sqrt((mean(x)-t)/(var(x)-t^2))
210
+ a <- m*(mean(x)-t)
211
+ res <- c(m, a, t)
212
+ return(res)
213
+ }
214
+ #' Auxiliar pwald function for the Ex-Wald distribution
215
+ #' @description This function emulates the pWALD function.
216
+ #' @param w a value for w.
217
+ #' @param m a value for m.
218
+ #' @param a a value for a.
219
+ #' @param s a value for s.
220
+ #' @return returns a vector with cumulative probabilities.
221
+ #' @keywords internal
222
+ #' @export
223
+ pwald <- function(w, m, a, s=0) {
224
+ w <- w - s;
225
+ sqrtw <- sqrt(w);
226
+ k1 <- (m*w-a)/sqrtw;
227
+ k2 <- (m*w+a)/sqrtw
228
+ p1 <- exp(2*a*m);
229
+ p2 <- pnorm(-k2);
230
+ bad <- (p1==Inf) | (p2==0);
231
+ p <- p1*p2
232
+ p[bad] <- (exp(-(k1[bad]^2)/2 - 0.94/(k2[bad]^2))/(k2[bad]*((2*pi)^.5)))
233
+ p + pnorm(k1)
234
+ }
235
+ #' Auxiliar function to generate random values for Ex-Wald distribution
236
+ #' @description This function generates another form to generate values.
237
+ #' @param x a value for x.
238
+ #' @param y a value for y.
239
+ #' @return returns a vector with values.
240
+ #' @keywords internal
241
+ #' @export
242
+ rew <- function(x, y) {
243
+ uv <- uandv(y, x)
244
+ exp(y^2-x^2)*(cos(2*x*y)*(1-uv[,1])+sin(2*x*y)*uv[,2])
245
+ }
246
+ #' Auxiliar den_exw function for the Ex-Wald distribution
247
+ #' @description This function emulates the dExWALD function.
248
+ #' @param r value for r.
249
+ #' @param m value for m.
250
+ #' @param a value for a.
251
+ #' @param t value for t.
252
+ #' @return returns a vector with probabilities.
253
+ #' @keywords internal
254
+ #' @export
255
+ den_exw <- function(r, m, a, t) {
256
+ k <- (m^2 - (2/t))
257
+ if (k < 0) {
258
+ res <- exp(m*a - (a^2)/(2*r) - r*(m^2)/2)*
259
+ rew(sqrt(-r*k/2), a/sqrt(2*r))/t
260
+ } else {
261
+ k <- sqrt(k)
262
+ res <- pwald(r,k,a)*exp(a*(m-k) - (r/t))/t
263
+ }
264
+ return(res)
265
+ }
266
+ #' Auxiliar function to obtain minus loglik for Ex-Wald
267
+ #' @description This function calculates minus loglik.
268
+ #' @param p a vector with the parameters.
269
+ #' @param x a vector with the random sample.
270
+ #' @return returns the minus loglik.
271
+ #' @keywords internal
272
+ #' @export
273
+ negllexw <- function(p, x) {
274
+ -sum(log(den_exw(x, p[1], p[2], p[3])))
275
+ }
276
+ #' Auxiliar function for the Ex-Wald distribution
277
+ #' @description This function generates starting values.
278
+ #' @param rt a vector with the random sample.
279
+ #' @param p a value for p.
280
+ #' @param start an optional start vector.
281
+ #' @param scaleit logical value to scale.
282
+ #' @return returns a vector with cumulative probabilities.
283
+ #' @keywords internal
284
+ #' @importFrom stats nlminb
285
+ #' @export
286
+ fitexw <- function(rt, p=0.5,
287
+ start=exwstpt(rt, p),
288
+ scaleit=TRUE){
289
+ if (scaleit)
290
+ fit <- nlminb(start=start,
291
+ lower=c(1e-8, 1e-8, 1),
292
+ objective=negllexw,
293
+ x=rt,
294
+ scale=(1/start),
295
+ control=list(eval.max=400, iter.max=300))
296
+ else
297
+ fit <- nlminb(start=start,
298
+ lower=c(1e-8, 1e-8, 1),
299
+ objective=negllexw,
300
+ x=rt,
301
+ control=list(eval.max=400, iter.max=300,
302
+ scale.tol=1e-8))
303
+
304
+ return(fit$par)
305
+ }
306
+
307
+
WALD.R ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #' The Wald family
2
+ #'
3
+ #' @author Sofia Cuartas Garc铆a, \email{scuartasg@unal.edu.co}
4
+ #'
5
+ #' @description
6
+ #' The function \code{WALD()} defines the wALD distribution, two-parameter
7
+ #' continuous distribution for a \code{gamlss.family} object to be used in GAMLSS fitting
8
+ #' using the function \code{gamlss()}.
9
+ #'
10
+ #' @param mu.link defines the mu.link, with "log" link as the default for the mu parameter.
11
+ #' @param sigma.link defines the sigma.link, with "log" link as the default for the sigma parameter.
12
+ #'
13
+ #' @references
14
+ #' Heathcote, A. (2004). Fitting Wald and ex-Wald distributions to
15
+ #' response time data: An example using functions for the S-PLUS package.
16
+ #' Behavior Research Methods, Instruments, & Computers, 36, 678-694.
17
+ #'
18
+ #' @seealso \link{dWALD}.
19
+ #'
20
+ #' @details
21
+ #' The Wald distribution with parameters \eqn{\mu} and \eqn{sigma} has density given by
22
+ #'
23
+ #' \eqn{\operatorname{f}(x |\mu, \sigma)=\frac{\sigma}{\sqrt{2 \pi x^3}} \exp \left[-\frac{(\sigma-\mu x)^2}{2x}\right ], x>0 }
24
+ #'
25
+ #' @returns Returns a gamlss.family object which can be used to fit a WALD distribution in the \code{gamlss()} function.
26
+ #'
27
+ #' @example examples/examples_WALD.R
28
+ #'
29
+ #' @importFrom gamlss.dist checklink
30
+ #' @importFrom gamlss rqres.plot
31
+ #' @export
32
+ WALD <- function (mu.link="log", sigma.link="log"){
33
+ mstats <- checklink("mu.link", "WALD",
34
+ substitute(mu.link),
35
+ c("log", "own"))
36
+ dstats <- checklink("sigma.link", "WALD",
37
+ substitute(sigma.link),
38
+ c("log", "own"))
39
+
40
+ structure(list(family=c("WALD", "Wald"),
41
+ parameters=list(mu=TRUE, sigma=TRUE),
42
+ nopar=2,
43
+ type="Continuous",
44
+
45
+ mu.link = as.character(substitute(mu.link)),
46
+ sigma.link = as.character(substitute(sigma.link)),
47
+
48
+ mu.linkfun = mstats$linkfun,
49
+ sigma.linkfun = dstats$linkfun,
50
+
51
+ mu.linkinv = mstats$linkinv,
52
+ sigma.linkinv = dstats$linkinv,
53
+
54
+ mu.dr = mstats$mu.eta,
55
+ sigma.dr = dstats$mu.eta,
56
+
57
+ # First derivates
58
+ dldm = function(y, mu, sigma) {
59
+ dldm <- sigma-mu*y
60
+ dldm
61
+ },
62
+
63
+ dldd = function(y, mu, sigma) {
64
+ dldd <- 1/sigma - (sigma-mu*y)/y
65
+ dldd
66
+ },
67
+
68
+ # Second derivates
69
+ d2ldm2 = function(y, mu, sigma) {
70
+ dm <- gamlss::numeric.deriv(dWALD(y, mu, sigma, log=TRUE),
71
+ theta="mu",
72
+ delta=0.0001)
73
+ dldm <- as.vector(attr(dm, "gradient"))
74
+ d2ldm2 <- - dldm * dldm
75
+ d2ldm2 <- ifelse(d2ldm2 < -1e-15, d2ldm2, -1e-15)
76
+ d2ldm2
77
+ },
78
+
79
+ d2ldmdd = function(y, mu, sigma) {
80
+ dm <- gamlss::numeric.deriv(dWALD(y, mu, sigma, log=TRUE),
81
+ theta="mu",
82
+ delta=0.0001)
83
+ dldm <- as.vector(attr(dm, "gradient"))
84
+ dd <- gamlss::numeric.deriv(dWALD(y, mu, sigma, log=TRUE),
85
+ theta="sigma",
86
+ delta=0.0001)
87
+ dldd <- as.vector(attr(dd, "gradient"))
88
+ d2ldmdd <- - dldm * dldd
89
+ d2ldmdd <- ifelse(d2ldmdd < -1e-15, d2ldmdd, -1e-15)
90
+ d2ldmdd
91
+ },
92
+
93
+ d2ldd2 = function(y, mu, sigma) {
94
+ dd <- gamlss::numeric.deriv(dWALD(y, mu, sigma, log=TRUE),
95
+ theta="sigma",
96
+ delta=0.0001)
97
+ dldd <- as.vector(attr(dd, "gradient"))
98
+ d2ldd2 <- - dldd * dldd
99
+ d2ldd2 <- ifelse(d2ldd2 < -1e-15, d2ldd2, -1e-15)
100
+ d2ldd2
101
+ },
102
+
103
+ G.dev.incr = function(y, mu, sigma, pw = 1, ...) -2*dWALD(y, mu, sigma, log=TRUE),
104
+ rqres = expression(rqres(pfun="pWALD", type="Continuous", y=y, mu=mu, sigma=sigma)),
105
+
106
+ mu.initial = expression(mu <- rep(wald_start(y)[1], length(y)) ),
107
+ sigma.initial = expression(sigma <- rep(wald_start(y)[2], length(y)) ),
108
+
109
+ mu.valid = function(mu) all(mu > 0),
110
+ sigma.valid = function(sigma) all(sigma > 0),
111
+
112
+ y.valid = function(y) all(y > 0),
113
+
114
+ mean = function(mu, sigma) sigma/mu,
115
+ variance = function(mu, sigma) sigma/(mu^3)
116
+ ),
117
+ class=c("gamlss.family", "family"))
118
+ }
119
+ #' Initial values for WALD
120
+ #' @description This function generates initial values for the parameters.
121
+ #' @param y vector with the response variable.
122
+ #' @return returns a vector with starting values.
123
+ #' @keywords internal
124
+ #' @export
125
+ #' @importFrom stats var
126
+ wald_start <- function(y) {
127
+ mu <- sqrt(mean(y)/var(y))
128
+ sigma <- mu*mean(y)
129
+ return(c(mu, sigma))
130
+ }
131
+
dExWALD.R ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #' The Ex-Wald distribution
2
+ #'
3
+ #' @author Freddy Hernandez, \email{fhernanb@unal.edu.co}
4
+ #'
5
+ #' @description
6
+ #' These functions define the density, distribution function, quantile
7
+ #' function and random generation for the Ex-Wald distribution
8
+ #' with parameter \eqn{\mu}, \eqn{\sigma} and \eqn{\nu}.
9
+ #'
10
+ #' @param x,q vector of (non-negative integer) quantiles.
11
+ #' @param p vector of probabilities.
12
+ #' @param mu vector of the mu parameter.
13
+ #' @param sigma vector of the sigma parameter.
14
+ #' @param nu vector of the nu parameter.
15
+ #' @param n number of random values to return.
16
+ #' @param log,log.p logical; if TRUE, probabilities p are given as log(p).
17
+ #' @param lower.tail logical; if TRUE (default), probabilities are
18
+ #' P[X <= x], otherwise, P[X > x].
19
+ #'
20
+ #' @seealso \link{ExWALD}
21
+ #'
22
+ #' @references
23
+ #' Schwarz, W. (2001). The ex-Wald distribution as a descriptive model
24
+ #' of response times. Behavior Research Methods,
25
+ #' Instruments, & Computers, 33, 457-469.
26
+ #'
27
+ #' Heathcote, A. (2004). Fitting Wald and ex-Wald distributions to
28
+ #' response time data: An example using functions for the S-PLUS package.
29
+ #' Behavior Research Methods, Instruments, & Computers, 36, 678-694.
30
+ #'
31
+ #' @details
32
+ #' The Wald distribution with parameters \eqn{\mu}, \eqn{\sigma}
33
+ #' and \eqn{\nu} has density given by
34
+ #'
35
+ #' \eqn{f(x |\mu, \sigma, \nu) = \frac{1}{\nu} \exp(\frac{-x}{\nu} + \sigma(\mu-k)) F_W(x|k, \sigma) \, \text{for} \, k \geq 0}
36
+ #'
37
+ #' \eqn{f(x |\mu, \sigma, \nu) = \frac{1}{\nu} \exp\left( \frac{-(\sigma-\mu)^2}{2x} \right) Re \left( w(k^\prime \sqrt{x/2} + \frac{\sigma i}{\sqrt{2x}}) \right) \, \text{for} \, k < 0}
38
+ #'
39
+ #' where \eqn{k=\sqrt{\mu^2-\frac{2}{\nu}}},
40
+ #' \eqn{k^\prime=\sqrt{\frac{2}{\nu}-\mu^2}} and
41
+ #' \eqn{F_W} corresponds to the cumulative function of
42
+ #' the Wald distribution.
43
+ #'
44
+ #' More details about those expressions
45
+ #' can be found on page 680 from Heathcote (2004).
46
+ #'
47
+ #' @return
48
+ #' \code{dExWALD} gives the density, \code{pExWALD} gives the distribution
49
+ #' function, \code{qExWALD} gives the quantile function, \code{rExWALD}
50
+ #' generates random deviates.
51
+ #'
52
+ #' @example examples/examples_dExWALD.R
53
+ #'
54
+ #' @export
55
+ dExWALD <- function(x, mu=1.5, sigma=1.5, nu=2, log=FALSE) {
56
+ if (any(mu<=0))
57
+ stop ("mu must be positive")
58
+ if (any(sigma<=0))
59
+ stop ("sigma must be positive")
60
+ if (any(nu<=0))
61
+ stop ("nu must be positive")
62
+
63
+ # Freddy's code
64
+ k <- mu^2 - 2/nu
65
+ if (k < 0) {
66
+ part1 <- -log(nu) + mu*sigma - sigma^2/(2*x) - x*mu^2/2
67
+ element1 <- sqrt(-x*k/2)
68
+ element2 <- sigma/sqrt(2*x)
69
+ element3 <- ifelse(element1 < 30 & element2 < 25,
70
+ rew(element1, element2),
71
+ 0)
72
+ element3 <- abs(element3)
73
+ part2 <- log(element3)
74
+ res <- part1 + part2
75
+ }
76
+ else {
77
+ k <- sqrt(k)
78
+ part1 <- -log(nu)
79
+ part2 <- sigma*(mu-k)-x/nu
80
+ part3 <- pWALD(x, mu=k, sigma=sigma, log.p=TRUE)
81
+ res <- part1 + part2 + part3 # Expression (3)
82
+ }
83
+
84
+ if (log)
85
+ return(res)
86
+ else
87
+ return(exp(res))
88
+ }
89
+ # Vectorizing
90
+ dExWALD <- Vectorize(dExWALD)
91
+ #' @export
92
+ #' @rdname dExWALD
93
+ pExWALD <- function(q, mu=1.5, sigma=1.5, nu=2,
94
+ lower.tail = TRUE, log.p = FALSE) {
95
+ if (any(mu<=0))
96
+ stop ("mu must be positive")
97
+ if (any(sigma<=0))
98
+ stop ("sigma must be positive")
99
+ if (any(nu<=0))
100
+ stop ("nu must be positive")
101
+
102
+ cdf <- pWALD(q, mu, sigma) - nu * dExWALD(q, mu, sigma, nu)
103
+ if (lower.tail == TRUE) {
104
+ cdf <- cdf
105
+ }
106
+ else {
107
+ cdf <- 1 - cdf
108
+ }
109
+ if (log.p == FALSE){
110
+ cdf <- cdf}
111
+ else {cdf <- log(cdf)}
112
+ return(cdf)
113
+ }
114
+ #' @export
115
+ #' @rdname dExWALD
116
+ #' @importFrom stats uniroot
117
+ qExWALD <- function(p, mu=1.5, sigma=1.5, nu=2) {
118
+ if (any(mu<=0))
119
+ stop ("mu must be positive")
120
+ if (any(sigma<=0))
121
+ stop ("sigma must be positive")
122
+ if (any(nu<=0))
123
+ stop ("nu must be positive")
124
+
125
+ # Begin auxiliar function
126
+ my_aux <- function(x, p, mu, sigma, nu)
127
+ pExWALD(x, mu, sigma, nu) - p
128
+ # End auxiliar function
129
+
130
+ uniroot(my_aux, c(0.001, 10000), tol=0.0001,
131
+ mu=mu, sigma=sigma, nu=nu, p=p)$root
132
+ }
133
+ # Vectorizing
134
+ qExWALD <- Vectorize(qExWALD)
135
+ #' @export
136
+ #' @rdname dExWALD
137
+ #' @importFrom stats rexp
138
+ rExWALD <- function(n, mu=1.5, sigma=1.5, nu=2) {
139
+ if (any(mu<=0))
140
+ stop ("mu must be positive")
141
+ if (any(sigma<=0))
142
+ stop ("sigma must be positive")
143
+ if (any(nu<=0))
144
+ stop ("nu must be positive")
145
+
146
+ rWALD(n, mu, sigma) + rexp(n, 1/nu)
147
+ }
148
+ #' Auxiliar function for the Ex-Wald distribution
149
+ #' @description This function is an auxiliar function.
150
+ #' @param x a value for x.
151
+ #' @param y a value for y.
152
+ #' @param block a value.
153
+ #' @param tol is the tolerance.
154
+ #' @param maxseries maximum value for series.
155
+ #' @return returns a vector with starting values.
156
+ #' @keywords internal
157
+ #' @export
158
+ uandv <- function(x, y, firstblock=20, block=0,
159
+ tol=.Machine$double.eps^(2/3), maxseries=20) {
160
+ twoxy <- 2*x*y; xsq <- x^2; iexpxsqpi <- 1/(pi*exp(xsq))
161
+ sin2xy <- sin(twoxy); cos2xy <- cos(twoxy)
162
+ nmat <- matrix(rep((1:firstblock), each = length(x)), nrow = length(x))
163
+ nsqmat <- nmat^2; ny <- nmat*y; twoxcoshny <- 2*x*cosh(ny)
164
+ nsinhny <- nmat*sinh(ny); nsqfrac <- (exp(-nsqmat/4)/(nsqmat+4*xsq))
165
+ u <- (2*pnorm(x*sqrt(2))-1)+iexpxsqpi*(((1-cos2xy)/(2*x))+2*
166
+ ((nsqfrac*(2*x-twoxcoshny*cos2xy+nsinhny*sin2xy))%*%rep(1, firstblock)))
167
+ v <- iexpxsqpi*((sin2xy/(2*x))+2*((nsqfrac*(twoxcoshny*sin2xy+
168
+ nsinhny*cos2xy))%*%rep(1,firstblock)))
169
+ n <- firstblock; converged <- rep(F, length(x))
170
+ repeat {
171
+ if ((block<1)||(n>=maxseries)) break
172
+ else {
173
+ if ((n+block)>maxseries) block <- (maxseries-n)
174
+ nmat <- matrix(rep((n+1):(n+block), each=sum(!converged)),
175
+ nrow=sum(!converged))
176
+ nsq <- nmat^2; ny <- nmat*y[!converged];
177
+ twoxcoshny <- 2*x[!converged]*cosh(ny); nsinhny <- nmat*sinh(ny)
178
+ nsqfrac <- (exp(-nsq/4)/(nsq+4*xsq[!converged]))
179
+ du <- iexpxsqpi[!converged]*((2*nsqfrac*(2*x[!converged]-
180
+ twoxcoshny*cos2xy[!converged]+nsinhny*sin2xy[!converged]))
181
+ %*%rep(1,block))
182
+ dv <- iexpxsqpi[!converged]*((2*nsqfrac*(twoxcoshny*sin2xy[!converged]+
183
+ nsinhny*cos2xy[!converged]))%*%rep(1, block))
184
+ u[!converged] <- u[!converged]+du;
185
+ v[!converged] <- v[!converged]+dv
186
+ converged[!converged] <- ((du<tol)&(dv<tol))
187
+ if (all(converged)) break
188
+ }
189
+ }
190
+ cbind(u,v)
191
+ }
192
+
dWALD.R ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #' The Wald distribution
2
+ #'
3
+ #' @author Sofia Cuartas, \email{scuartasg@unal.edu.co}
4
+ #'
5
+ #' @description
6
+ #' These functions define the density, distribution function, quantile
7
+ #' function and random generation for the Wald distribution
8
+ #' with parameter \eqn{\mu} and \eqn{\sigma}.
9
+ #'
10
+ #' @param x,q vector of (non-negative integer) quantiles.
11
+ #' @param p vector of probabilities.
12
+ #' @param mu vector of the mu parameter.
13
+ #' @param sigma vector of the sigma parameter.
14
+ #' @param n number of random values to return.
15
+ #' @param log,log.p logical; if TRUE, probabilities p are given as log(p).
16
+ #' @param lower.tail logical; if TRUE (default), probabilities are
17
+ #' P[X <= x], otherwise, P[X > x].
18
+ #'
19
+ #' @seealso \link{WALD}
20
+ #'
21
+ #' @references
22
+ #' Heathcote, A. (2004). Fitting Wald and ex-Wald distributions to
23
+ #' response time data: An example using functions for the S-PLUS package.
24
+ #' Behavior Research Methods, Instruments, & Computers, 36, 678-694.
25
+ #'
26
+ #' @seealso \link{WALD}.
27
+ #'
28
+ #' @details
29
+ #' The Wald distribution with parameters \eqn{\mu} and \eqn{\sigma} has density given by
30
+ #'
31
+ #' \eqn{f(x |\mu, \sigma)=\frac{\sigma}{\sqrt{2 \pi x^3}} \exp \left[-\frac{(\sigma-\mu x)^2}{2x}\right ],}
32
+ #'
33
+ #' for \eqn{x < 0}.
34
+ #'
35
+ #' @return
36
+ #' \code{dWALD} gives the density, \code{pWALD} gives the distribution
37
+ #' function, \code{qWALD} gives the quantile function, \code{rWALD}
38
+ #' generates random deviates.
39
+ #'
40
+ #' @example examples/examples_dWALD.R
41
+ #'
42
+ #' @export
43
+ dWALD <- function(x, mu, sigma, log=FALSE) {
44
+ if (any(x <= -1e-15)) stop(paste("x must be positive", "\n", ""))
45
+ if (any(mu <= 0)) stop(paste("mu must be positive 0", "\n", ""))
46
+ if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
47
+
48
+ res <- log(sigma) - 0.5*log(2*pi) - 1.5*log(x) - (sigma-mu*x)^2/(2*x)
49
+
50
+ if(log == FALSE)
51
+ return(exp(res))
52
+ else
53
+ return(res)
54
+ }
55
+ #' @export
56
+ #' @rdname dWALD
57
+ #' @importFrom stats pnorm
58
+ pWALD <- function(q, mu , sigma, lower.tail = TRUE, log.p = FALSE){
59
+ if (any(q <= -1e-15)) stop(paste("q must be positive", "\n", ""))
60
+ if (any(mu <= 0)) stop(paste("mu must be positive", "\n", ""))
61
+ if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
62
+ sqrtq <- sqrt(q)
63
+ k1 <- (mu*q-sigma)/sqrtq
64
+ k2 <- (mu*q+sigma)/sqrtq
65
+ p1 <- exp(2*sigma*mu)
66
+ p2 <- pnorm(-k2)
67
+ bad <- (p1==Inf) | (p2==0)
68
+ p <- p1*p2
69
+ p[bad] <- (exp(-(k1[bad]^2)/2 - 0.94/(k2[bad]^2))/(k2[bad]*((2*pi)^.5)))
70
+ cdf <- p + pnorm(k1)
71
+ if (lower.tail == TRUE) {
72
+ cdf <- cdf
73
+ }
74
+ else {
75
+ cdf <- 1 - cdf
76
+ }
77
+ if (log.p == FALSE){
78
+ cdf <- cdf}
79
+ else {cdf <- log(cdf)}
80
+ return(cdf)
81
+ }
82
+ #' @export
83
+ #' @rdname dWALD
84
+ qWALD <- function(p, mu, sigma, lower.tail=TRUE, log.p=FALSE){
85
+ if (any(mu <= 0)) stop(paste("mu must be positive 0", "\n", ""))
86
+ if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
87
+
88
+ if (log.p == TRUE) p <- exp(p)
89
+ else p <- p
90
+ if (lower.tail == TRUE) p <- p
91
+ else p <- 1 - p
92
+
93
+ if (any(p < 0) | any(p > 1)) stop(paste("p must be between 0 and 1", "\n", ""))
94
+
95
+ F.inv <- function(y, mu, sigma, nu) {
96
+ uniroot(function(x) {pWALD(x,mu,sigma) - y},
97
+ interval=c(0, 99999))$root
98
+ }
99
+ F.inv <- Vectorize(F.inv)
100
+ F.inv(p, mu, sigma)
101
+ }
102
+ #' @export
103
+ #' @rdname dWALD
104
+ #' @importFrom stats rchisq
105
+ rWALD <- function(n, mu, sigma){
106
+ if (any(n <= 0)) stop(paste("n must be positive","\n",""))
107
+ if (any(mu <= 0)) stop(paste("mu must be positive 0", "\n", ""))
108
+ if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
109
+ y2 <- rchisq(n, 1)
110
+ y2onm <- y2/mu
111
+ u <- runif(n)
112
+ r1 <- (2*sigma + y2onm - sqrt(y2onm*(4*sigma+y2onm)))/(2*mu)
113
+ r2 <- (sigma/mu)^2/r1
114
+ r <- ifelse(u < sigma/(sigma+mu*r1), r1, r2)
115
+ r
116
+ }
server.R ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ source("dWALD.R")
2
+ source("WALD.R")
3
+ source("dExWALD.R")
4
+ source("ExWALD.R")
5
+
6
+ library(shiny)
7
+ library(MASS)
8
+ library(gamlss)
9
+
10
+ shinyServer(function(input, output) {
11
+
12
+ datos_reactivo <- reactive({
13
+ req(input$datos)
14
+
15
+ datos_char <- unlist(strsplit(input$datos, ","))
16
+ datos_num <- as.numeric(trimws(datos_char))
17
+ datos_num <- datos_num[!is.na(datos_num)]
18
+
19
+ if(length(datos_num) == 0) {
20
+ return(NULL)
21
+ } else {
22
+ return(datos_num)
23
+ }
24
+ })
25
+
26
+ output$histograma <- renderPlot({
27
+ datos <- datos_reactivo()
28
+ req(datos)
29
+
30
+ dist_sel <- input$dist
31
+
32
+ #par(mfrow=c(2, 1))
33
+
34
+ hist(datos, probability = TRUE, col = "lightblue",
35
+ main = paste("Histogram and estimated density for", dist_sel),
36
+ xlab = "x")
37
+
38
+ x_seq <- seq(min(datos), max(datos), length.out = 200)
39
+
40
+ # Estimation y curva seg煤n distribuci贸n elegida
41
+ if(dist_sel == "Normal") {
42
+
43
+ fit <- gamlss(datos~1, family=NO)
44
+ mu <- coef(fit, what="mu")
45
+ sigma <- exp(coef(fit, what="sigma"))
46
+ y <- dNO(x_seq, mu = mu, sigma = sigma)
47
+ lines(x_seq, y, col = "tomato", lwd=3)
48
+ legend("topright", bty="n",
49
+ legend="Estimated density",
50
+ lwd=3, col="tomato")
51
+
52
+ } else if(dist_sel == "WALD") {
53
+ # Ajuste con fitdistr
54
+ fit <- tryCatch({
55
+ mod <- gamlss(datos~1, family=WALD)
56
+ }, error = function(e) NULL)
57
+
58
+ if(!is.null(fit)) {
59
+ mu <- exp(coef(fit, what="mu"))
60
+ sigma <- exp(coef(fit, what="sigma"))
61
+ y <- dWALD(x_seq, mu=mu, sigma=sigma)
62
+ lines(x_seq, y, col = "tomato", lwd=3)
63
+ }
64
+
65
+ } else if(dist_sel == "ExWALD") {
66
+ fit <- tryCatch({
67
+ fit <- gamlss(datos~1, family=ExWALD)
68
+ }, error = function(e) NULL)
69
+
70
+ if(!is.null(fit)) {
71
+ mu <- exp(coef(fit, what="mu"))
72
+ sigma <- exp(coef(fit, what="sigma"))
73
+ nu <- exp(coef(fit, what="nu"))
74
+ y <- dExWALD(x_seq, mu=mu, sigma=sigma, nu=nu)
75
+ lines(x_seq, y, col = "tomato", lwd=3)
76
+ }
77
+ }
78
+ # To plot the residual analysis
79
+ #plot(fit)
80
+ })
81
+
82
+ output$parametros <- renderTable({
83
+ datos <- datos_reactivo()
84
+ req(datos)
85
+
86
+ dist_sel <- input$dist
87
+
88
+ if(dist_sel == "Normal") {
89
+ mu <- mean(datos)
90
+ sigma <- sd(datos)
91
+ data.frame(
92
+ Parameter = c("渭", "蟽", "Mean", "Standard deviation"),
93
+ Estimation = c(mu, sigma, mean(datos), sd(datos))
94
+ )
95
+
96
+ } else if(dist_sel == "WALD") {
97
+ fit <- tryCatch({
98
+ mod <- gamlss(datos~1, family=WALD)
99
+ }, error = function(e) NULL)
100
+
101
+ if(!is.null(fit)) {
102
+ mu <- exp(coef(fit, what="mu"))
103
+ sigma <- exp(coef(fit, what="sigma"))
104
+ data.frame(
105
+ Parameter = c("渭", "蟽", "Mean", "Standard deviation"),
106
+ Estimation = c(mu, sigma, mean(datos), sd(datos))
107
+ )
108
+ } else {
109
+ data.frame(
110
+ Parameter = "Error",
111
+ Estimation = "We cannot fit WALD"
112
+ )
113
+ }
114
+
115
+ } else if(dist_sel == "ExWALD") {
116
+ fit <- tryCatch({
117
+ fit <- gamlss(datos~1, family=ExWALD)
118
+ }, error = function(e) NULL)
119
+
120
+ if(!is.null(fit)) {
121
+ mu <- exp(coef(fit, what="mu"))
122
+ sigma <- exp(coef(fit, what="sigma"))
123
+ nu <- exp(coef(fit, what="nu"))
124
+ data.frame(
125
+ Parameter = c("渭", "蟽", "谓", "Mean", "Standard deviation"),
126
+ Estimation = c(mu, sigma, nu, mean(datos), sd(datos))
127
+ )
128
+ } else {
129
+ data.frame(
130
+ Parameter = "Error",
131
+ Estimation = "We cannot fit ExWALD"
132
+ )
133
+ }
134
+ }
135
+ })
136
+
137
+ })
ui.R ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ library(shiny)
2
+
3
+ shinyUI(fluidPage(
4
+ titlePanel("Shiny app to estimate parameters for Reaction Times (RTs)"),
5
+
6
+ sidebarLayout(
7
+ sidebarPanel(
8
+ textInput("datos", "Enter numbers separated by commas:",
9
+ placeholder = "Example: 1.2, 3.4, 2.1, 5.6, 4.3"),
10
+
11
+ selectInput("dist", "Select the distribution:",
12
+ choices = c("Normal", "WALD", "ExWALD"),
13
+ selected = "Normal"),
14
+ br(),
15
+ p("Example 1"),
16
+ p("The next random sample was obtained from a N(15, 3),"),
17
+ p("copy and paste the next numbers:"),
18
+ p("16.5, 19.8, 11.8, 14.6, 14.2, 5.8, 12.8, 17.5, 22.9, 7.5, 9.4,
19
+ 14.8, 15.3, 12.9, 12.6, 13.4, 20.2, 16.4, 18.4, 15, 15.1, 18.1,
20
+ 15.9, 16.5, 15.1, 15, 17, 16.5, 19.9, 11.9, 14.1, 13.1, 12, 15.8,
21
+ 16.3, 16.1, 13.3, 11.2, 17.8, 17.9, 11.4, 15.6, 10.7, 15.1, 13.3,
22
+ 16.6, 15.5, 12.2, 14.6, 15.2"),
23
+ br(),
24
+ p("Example 3"),
25
+ p("The next random sample was obtained from a ExWALD(2, 5, 1.2),"),
26
+ p("copy and paste the next numbers:"),
27
+ p("2.3, 3.8, 3.1, 3.9, 3.2, 3.8, 2.8, 1.3, 4.2, 2.3, 2.9, 2.6,
28
+ 3.8, 5, 4.6, 3.5, 9.6, 2.3, 3.9, 3.1, 8.6, 2.2, 5.6, 2.7, 2,
29
+ 3.5, 5.4, 5.1, 3, 2, 5.1, 4.6, 3.7, 3.6, 2.3, 2.3, 3.6, 1.6,
30
+ 3.6, 2.9, 3.1, 5.4, 3.2, 2.4, 3.4, 3.7, 4.4, 6.3, 2.9, 3.2")
31
+ ),
32
+
33
+ mainPanel(
34
+ plotOutput("histograma"),
35
+ tableOutput("parametros")
36
+ )
37
+ )
38
+ ))