/
classesArr.R
571 lines (531 loc) · 20.1 KB
/
classesArr.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# classesArr.R - Array-based classes
# FLCore/R/classesArr.R
# Copyright 2003-2015 FLR Team. Distributed under the GPL 2 or later
# Maintainer: Iago Mosqueira, EC JRC G03
# FLArray {{{
#' Class FLArray
#'
#' A basic 6D array class. No objects of this class are created in
#' FLCore, as it is used only for method inheritance.
#'
#' @name FLArray
#' @aliases FLArray FLArray-class
#' @docType class
#' @section Slots: \describe{
#' \item{.Data}{Internal S4 data representation, of class \code{array}.}
#' }
#' @section Validity: \describe{
#' \item{Dimensions:}{Array must have 6 dimensions}
#' \item{Content:}{Array must be of class \code{numeric}}
#' }
#' @author The FLR Team
#' @seealso \code{\linkS4class{FLQuant}}, \code{\linkS4class{FLCohort}}
#' @keywords classes
setClass("FLArray", representation("array"),
prototype(array(as.numeric(NA), dim=c(1,1,1,1,1,1))),
validity=function(object){
# Make sure there are at least 6 dimensions in the array
Dim <- dim(object)
if (length(Dim) != 6)
return("the array must have 6 dimensions")
if (!is.numeric(object) && !is.na(object))
return("array is not numeric")
# Everything is fine
return(TRUE)
}
) # }}}
# FLQuant {{{
#' FLQuant class for numerical data
#'
#' The \code{FLQuant} class is a six-dimensional \code{\link[base]{array}}
#' designed to store most quantitative data used in fisheries and population
#' modelling.
#'
#' The six dimensions are named. The name of the first dimension can be
#' altered by the user from its default, \code{quant}. This could typically be
#' \code{age} or \code{length} for data related to natural populations. The
#' only name not accepted is 'cohort', as data structured along cohort should
#' be stored using the \code{\link{FLCohort}} class instead. Other dimensions
#' are always names as follows: \code{year}, for the calendar year of the
#' datapoint; \code{unit}, for any kind of division of the population, e.g. by
#' sex; \code{season}, for any temporal strata shorter than year; \code{area},
#' for any kind of spatial stratification; and \code{iter}, for replicates
#' obtained through bootstrap, simulation or Bayesian analysis.
#'
#' In addition, \code{FLQuant} objects contain a \code{units} attribute, of
#' class \code{\link[base]{character}}, intended to contain the units of
#' measurement relevant to the data.
#'
#' @name FLQuant
#' @aliases FLQuant-class FLQuant FLQuant-methods
#' FLQuant,FLQuant-method
#' @family FLCoreClasses
#' @docType class
#'
#' @section Slots: \describe{
#' \item{.Data}{A 6-D array for numeric data. \code{\link[base]{array}}.}
#' \item{units}{Units of measurement. \code{\link[base]{character}}.} }
#' @section Validity: \describe{
#' \item{Dimensions:}{Array must have 6 dimensions}
#' \item{Content:}{Array must be of class \code{numeric}}
#' \item{Dimnames:}{Dimensions 2 to 6 must be named "year", "unit", "season", "area" and "iter"}
#' }
#'
#' @section Constructor:
#' The \code{FLQuant} method provides a flexible constructor for objects of the class.
#' Inputs can be of class:
#' \describe{
#' \item{\code{vector}:}{A numeric vector will be placed along the year dimension by default.}
#' \item{\code{matrix}:}{A matrix will be placed along dimensions 1 and 2, unless otherwise specified by 'dim'. The matrix dimnames will be used unless overriden by 'dimnames'.}
#' \item{\link[base]{array}:}{As above}
#' \item{\link[base]{missing}:}{If no input is given, an empty \code{FLQuant} (NA) is returned, but dimensions and dimnames can still be specified.} }
#'
#' Additional arguments to the constructor:
#' \describe{
#' \item{units:}{The units of measurement, a \code{\link[base]{character}} string.}
#' \item{dim:}{The dimensions of the object, a \code{\link[base]{numeric}} vector of length 6.}
#' \item{dimnames:}{A \code{\link[base]{list}} object providing the dimnames of the array. Only those different from the default ones need to be specified.}
#' \item{quant:}{The name of the first dimension, if different from 'quant', as a \code{\link[base]{character}} string.} }
#' @param object Input numeric object
#' @param dim Vector of dimension lengths
#' @param dimnames List of dimension names
#' @param quant Character vector for name of first dimension
#' @param units Character vctor of units of measurement, see \link[FLCore]{uom}
#' @param iter Number of iterations, i.e. length of the 6th dimension
#' @param fill.iter Should iterations be filled with the same content as the first?
#' @param ... Additional arguments
#'
#' @author The FLR Team
#' @seealso \code{\linkS4class{FLQuant}}
#' @keywords classes
#' @examples
#'
#' # creating a new FLQuant
#' flq <- FLQuant()
#' flq <- FLQuant(1:10, dim=c(2,5))
#' summary(flq)
#'
#' # Vectors are used column first...
#' dim(FLQuant(1:10))
#' # ...while matrices go row first.
#' dim(FLQuant(matrix(1:10)))
#'
#' FLQuant(matrix(rnorm(100), ncol=20))
#'
#' FLQuant(array(rnorm(100), dim=c(5,2,1,1,1,10)))
#' FLQuant(array(rnorm(100), dim=c(5,2)), iter=10)
#'
#' # working with FLQuant objects
#' flq <- FLQuant(rnorm(200), dimnames=list(age=1:5, year=2000:2008), units='diff')
#' summary(flq)
#'
#' flq[1,]
#' flq[,1]
#' flq[1,1] <- 0
#'
#' units(flq)
#' quant(flq)
#'
#' plot(flq)
#'
setClass("FLQuant",
representation("FLArray", units="character"),
prototype(new('FLArray', array(as.numeric(NA), dim=c(1,1,1,1,1,1),
dimnames=list(quant="all", year="1", unit="unique", season="all",
area="unique", iter="1"))), units="NA"),
# VALIDITY
validity=function(object){
DimNames <- names(dimnames(object))
# First dimension cannot be called cohort
if(DimNames[1] == "cohort")
return("first dimension cannot be named 'cohort'")
# Make sure there are at least 6 dimensions in the array named
if (length(DimNames) != 6)
return("the array must have 6 dimensions")
# *, "year", "unit", "season", "area" and "iter"
if (!all(DimNames[2:6] == c("year", "unit", "season", "area", "iter")))
return("dimension names of the array are incorrect")
# array is numeric
if (!is.numeric(object) && !is.na(object))
return("array is not numeric")
# Everything is fine
return(TRUE)
}) # }}}
# FLQuantPoint {{{
#' Class FLQuantPoint
#'
#' The \code{FLQuantPoint} class summarizes the contents of an \code{FLQuant}
#' object with multiple iterations along its sixth dimension using a number of
#' descriptive statistics.
#'
#' An object of this class has a set structure along its sixth dimension
#' (\emph{iter}), which will always be of length 5, and with dimnames
#' \emph{mean}, \emph{median}, \emph{var}, \emph{uppq} and \emph{lowq}. They
#' refer, respectively, to the sample mean, sample median, variance, and lower
#' (0.25) and upper (0.75) quantiles.
#'
#' Objects of this class wil be typically created from an \code{FLQuant}. The
#' various statistics are calculated along the \emph{iter} dimension of the
#' original \code{FLQuant} using \code{\link[base]{apply}}.
#'
#' @name FLQuantPoint
#' @aliases FLQuantPoint-class FLQuantPoint FLQuantPoint-methods
#' FLQuantPoint,FLQuant-method
#' mean,FLQuantPoint-method mean<-,FLQuantPoint,FLQuant-method
#' median,FLQuantPoint-method median<-,FLQuantPoint,FLQuant-method
#' var,FLQuantPoint-method var<-,FLQuantPoint,FLQuant-method
#' lowq,FLQuantPoint-method lowq<-,FLQuantPoint,FLQuant-method
#' uppq,FLQuantPoint-method uppq<-,FLQuantPoint,FLQuant-method
#' quantile,FLQuantPoint-method
#' @docType class
#' @section Slots: \describe{
#' \item{.Data}{The main array holding the computed statistics. \code{array}.}
#' \item{units}{Units of measurement. \code{character}.}
#' }
#' @section Accesors: \describe{
#' \item{mean,mean<-:}{'mean' element on 6th dimension, arithmetic mean.}
#' \item{median,median<-:}{'median' element on 6th dimension, median.}
#' \item{var,var<-:}{'var' element on 6th dimension, variance.}
#' \item{lowq,lowq<-:}{'lowq' element on 6th dimension, lower quantile (0.25 by default).}
#' \item{uppq,uppq<-:}{'uppq' element on 6th dimension, upper quantile (0.75 by default).}
#' \item{quantile:}{returns the 'lowq' or 'uppq' iter, depending on the value of 'probs' (0.25 or 0.75).}
#' }
#' @section Constructor:
#' Inputs can be of class:
#' \describe{
#' \item{\code{FLQuant}:}{An FLQuant object with iters (i.e. dim[6] > 1)}
#' }
#' @section Validity: \describe{
#' \item{iter:}{iter dimension is of length 5.}
#' \item{Dimnames:}{iter dimnames are 'mean', 'median', 'var', 'uppq' and'lowq'}
#' }
#' @param object Input numeric object
#' @param ... Additonal arguments
#' @author The FLR Team
#' @seealso \link{FLQuant}
#' @keywords classes
#' @examples
#'
#' flq <- FLQuant(rlnorm(2000), dim=c(10,20,1,1,1,200), units="kg")
#' flqp <- FLQuantPoint(flq)
#' flqp <- FLQuantPoint(flq, probs=c(0.05, 0.95))
#' summary(flqp)
#' mean(flqp)
#' var(flqp)
#' rnorm(200, flqp)
setClass("FLQuantPoint",
representation("FLQuant", n="numeric"),
prototype(new('FLQuant', array(as.numeric(NA), dim=c(1,1,1,1,1,5),
dimnames=list(quant="all", year="1", unit="unique", season="all",
area="unique", iter=c('mean', 'median', 'var', 'uppq', 'lowq'))), units="NA"), n=1),
# VALIDITY
validity=function(object) {
# iter dimensions is of length 5 and with names:
if(dim(object)[6] != 5)
return("dims of object do not match those of the FLQuantPoint class")
# dimnames are 'mean', 'median', 'var', 'uppq', 'lowq'
if(any(dimnames(object)$iter != c('mean', 'median', 'var', 'uppq', 'lowq')))
return("dimnames of object do not match those of the FLQuantPoint class")
#
if(length(n) != 1)
return("'n' must be of length 1")
# Everything is fine
return(TRUE)
}
) # }}}
# FLQuantDistr {{{
#' A class for samples of a probability distribution
#'
#' This extended FLQuant class holds both a measure of central tendendy (mean,
#' median) and of dispersion (tipically variance), to be later used to generate,
#' for example, random numbers with those mean and variances.
#'
#' @name FLQuantDistr
#' @docType class
#' @rdname FLQuantDistr
#' @aliases FLQuantDistr-class
#' @section Slots:
#' \describe{
#' \item{.Data}{Unnamed slot for storing the mean (or other measure of
#' expectation) (\code{FLQuant}).}
#' \item{var}{Variance, or other measure of dispersion, (\code{FLQuant}).}
#' \item{distr}{Name of the probability distribution, see Details
#' (\code{character}).}
#' }
#'
#' @section Validity:
#'
#' \describe{
#' \item{slot dims}{.Data and var slots must have the same dimensions.}
#' \item{slot dimnames}{.Data and var slots must have the same dimnames.}
#' }
#'
#' You can inspect the class validity function by using
#' \code{getValidity(getClassDef('FLQuantDistr'))}
#'
#' @section Accessors:
#' All slots in the class have accessor and replacement methods defined that
#' allow retrieving and substituting individual slots.
#'
#' The values passed for replacement need to be of the class of that slot.
#' A numeric vector can also be used when replacing FLQuant slots, and the
#' vector will be used to substitute the values in the slot, but not its other
#' attributes.
#'
#' The contents of the unnamed slot (.Data) can be accessed through the
#' \code{e()} method, see Example below.
#'
#' @section Constructor:
#' A construction method exists for this class that can take named arguments for
#' any of its slots. All slots are then created to match the requirements of the
#' class validity. If an unnamed \code{FLQuant} object is provided, this is used
#' for the .Data slot.
#' @param object Input numeric object
#' @param ... Additonal arguments
#'
#' @section Methods:
#' Methods exist for various calculations based on values stored in the class:
#'
#' \describe{
#' \item{Arith}{.}
#' }
#' @section Arithmetic:
#' The methods under the \emph{Arith} group have been defined for objects of
#' this class, both for operations between two \code{FLQuantDistr} objects and
#' with objects of class \code{FLQuant} (\code{FLArray}) as follows:
#'
#' \describe{
#' \item{+, FLQuantDistr,FLArray}{.}
#' \item{-, FLQuantDistr,FLArray}{.}
#' \item{*, FLQuantDistr,FLArray}{.}
#' \item{/, FLQuantDistr,FLArray}{.}
#' \item{+, FLQuantDistr,FLQuantDistr}{.}
#' \item{-, FLQuantDistr,FLQuantDistr}{.}
#' \item{*, FLQuantDistr,FLQuantDistr}{.}
#' }
#' @author The FLR Team
#' @seealso \link{FLQuant}
#' @keywords classes
#' @examples
#'
#' data(ple4)
#' fqd <- FLQuantDistr(catch.n(ple4), var=catch.n(ple4) * 10, distr='norm')
#'
setClass("FLQuantDistr",
representation("FLQuant", var="FLQuant", distr="character"),
prototype(new("FLQuant"), var=new("FLQuant"), distr="norm"),
# VALIDITY
validity=function(object) {
# .Data & var have same dims
if(!all(dim(object@.Data) == dim(object@var)))
return("object slots' dimensions must match")
# .Data & var have same dimnames
if(!all.equal(dimnames(object@.Data), dimnames(object@var)))
return("object slots' dimnames must match")
# Everything is fine
return(TRUE)
}) # }}}
# FLQuantJK {{{
#' A class for jackknifing fisheries data
#'
#' This extended FLQuant class holds both a jackknifed FLQuant, one in which each
#' iter is missing one element, and the original object, as a separate
#' \code{FLQuant} in the \code{orig} slot.
#'
#' @name FLQuantJK
#' @docType class
#' @aliases FLQuantJK-class
#'
#' @section Slots:
#' \describe{
#' \item{.Data}{Unnamed slot containing the jackknifed object(\linkS4class{FLQuant}).}
#' \item{orig}{Original object, (\linkS4class{FLQuant}).}
#' }
#'
#' @section Validity:
#'
#' \describe{
#' \item{slot dims}{.Data and orig slots must have the same dimensions 1-5.}
#' \item{slot dimnames}{.Data and var slots must have the same dimnames 1-5.}
#' }
#'
#' You can inspect the class validity function by using
#' \code{getValidity(getClassDef('FLQuantJK'))}
#'
#' @section Accessors:
#' All slots in the class have accessor and replacement methods defined that
#' allow retrieving and substituting individual slots.
#'
#' The values passed for replacement need to be of the class of that slot.
#' A numeric vector can also be used when replacing FLQuant slots, and the
#' vector will be used to substitute the values in the slot, but not its other
#' attributes.
#'
#' @section Constructor:
#' Objects of this class must be constructed from an \linkS4class{FLQuant} that
#' is to be jackknifed, through the \code{\link{jackknife}} method.
#' @param object Input numeric object
#' @param ... Additonal arguments
#'
#' @section Methods:
#' All methods defined for the \linkS4class{FLQuant} class are available, but
#' they will operate only on the jackknifed (\code{.Data}) slot. Please use
#' \code{orig()} to apply them to the original object stored in the class.
#'
#' @author The FLR Team
#' @seealso \link{FLQuant}
#' @keywords classes
#' @examples
#'
#' data(ple4)
#' fjk <- jackknife(stock(ple4))
#' # New object has as many iters as length of jackknifed dimension (defaults to 'year')
#' dim(fjk)
#'
setClass("FLQuantJK",
representation("FLQuant", orig="FLQuant"),
prototype(new("FLQuant"), orig=new("FLQuant")),
validity=function(object) {
# if(!all.equal(dimnames(object@.Data)[1:5], dimnames(object@orig)[1:5]))
# return("Original and jackknifed object must share dimnames[1-5]")
return(TRUE)
}
) # }}}
# FLCohort {{{
#' Class FLCohort
#'
#' A class for modelling cohorts.
#'
#' This class represents cohorts in columns. It simply shifts the typical
#' matrix representation where cohorts are found on the diagonals, into a
#' matrix where cohorts are found in columns. It is very usefull for all
#' analysis that want to make use of cohorts instead of years.
#'
#' @name FLCohort
#' @aliases FLCohort FLCohort-class FLCohort-methods
#' @docType class
#' @section Slots: \describe{ \item{.Data}{Internal S4 data representation.
#' \code{array}.} \item{units}{The data units in some understandable metric.
#' \code{character}} }
#' @author The FLR Team
#' @seealso \link{[}, \link{as.data.frame}, \link{bubbles}, \link{ccplot},
#' \link{FLCohort,FLQuant-method}, \link{flc2flq}, \link[graphics]{plot},
#' \link{quant}, \link{trim}, \link{units},
#' \link{units<-,FLCohort,character-method}, \link[lattice]{xyplot},
#' \link[base]{array}
#' @keywords classes
#' @examples
#'
#' data(ple4)
#' flq <- catch.n(ple4)
#' flc <- FLCohort(flq)
#' plot(trim(flc, cohort=1960:2000))
#'
setClass("FLCohort",
representation("FLArray", units="character"),
prototype(array(as.numeric(NA), dim=c(1,1,1,1,1,1),
dimnames=list(age="1", cohort="1", unit="unique", season="all", area="unique",
iter="none")), units="NA"),
validity=function(object) {
# names
if(!all.equal(names(dimnames(object)),
c("age", "cohort", "unit", "season", "area", "iter")))
return("names of FLCohort object are not correct")
# Everything is fine
return(TRUE)
}
) # }}}
# FLPar {{{
#' Class FLPar
#'
#' A class for storing parameters of a model.
#'
#' The \code{FLPar} class is based on the array class which can store
#' Monte Carlo samples and the names of the relevant parameter vectors.
#'
#' Methods for this class include subsetting and replacement as for the
#' \code{\linkS4class{FLQuant}} class. There are methods for extracting
#' statistics of the sample (mean, median etc.) and for plotting the parameter
#' samples.
#'
#' @name FLPar
#' @aliases FLPar-class FLPar FLPar-methods FLPar,array-method
#' FLPar,missing-method FLPar,vector-method FLPar,FLPar-method
#' @docType class
#' @section Slots: \describe{ \item{.Data}{Describe slot. \code{array}.}
#' \item{units}{Units of measurement. \code{character}.} }
#' @author The FLR Team
#' @seealso \link[base]{[}, \link[base]{[<-}, \link[base]{as.data.frame},
#' \link[lattice]{densityplot}, \link[lattice]{histogram}, \link{iter},
#' \link{iter<-}, \link[base]{mean}, \link[stats]{median},
#' \link[graphics]{plot}, \link[lattice]{splom}, \link[base]{summary},
#' \link{units,FLPar-method}, \link{units<-,FLPar,character-method},
#' \link[stats]{var}
#' @keywords classes
#' @examples
#'
#' FLPar(rnorm(4), params=c('a','b','c','sigma2'))
#'
#' FLPar(rnorm(20), dimnames=list(params=c('a','b'), year=1990:1999, iter=1),
#' units='NA')
#'
#' # with iters
#' FLPar(rnorm(80), params=c('a', 'b'), iter=1:40)
#'
setClass('FLPar', representation('array', units='character'),
prototype=prototype(array(as.numeric(NA), dim=c(1,1),
dimnames=list(params=character(1), iter=1)), units='NA'),
validity=function(object) {
# object must be numeric
if(!is.numeric(object))
return('object must be numeric')
# Last dimension is called 'iter' ...
if(names(dimnames(object))[length(dim(object))] != "iter")
return("last dimension must be named 'iter'")
# ... and the first 'param'
# if(names(dimnames(object))[1] != "params")
# return("first dimension must be named 'params'")
return(TRUE)
}
) # }}}
# FLParJK {{{
#' Class FLParJK
#'
#' A class for storing parameters of a jackknifed model fit.
#'
#' @name FLParJK
#' @aliases FLParJK-class FLParJK
#' @docType class
#' @md
#' @slot .Data Jackknifed object, `FLPar`.
#' @slot units units of measurement, `character`.
#' @slot orig original object being jackknifed, `FLPar`.
#' @section Validity:
#' You can inspect the class validity function by using
#' `getValidity(getClassDef('FLParJK'))`
#' @section Accessors:
#' All slots in the class have accessor and replacement methods defined that
#' allow retrieving and substituting individual slots.
#'
#' The values passed for replacement need to be of the class of that slot.
#' A numeric vector can also be used when replacing FLQuant slots, and the
#' vector will be used to substitute the values in the slot, but not its other
#' attributes.
#' @section Constructor:
#' Objects of this class are commonly created by calling the [jackknife()] method
#' A construction method exists for this class that can take named arguments for
#' any of its slots. All slots are then created to match the requirements of the
#' class validity.
#' @author The FLR Team
#' @seealso [`FLPar`]
#' @keywords classes
setClass("FLParJK",
representation("FLPar", orig="FLPar"),
prototype(new("FLPar"), orig=new("FLPar")),
validity=function(object) {
# dimnames of .Data and origin, but 'iter', must mjatch
if(!all.equal(dimnames(object@.Data)[ - length(dim(object))],
dimnames(object@orig)[ - length(dim(object))]))
return("dimnames of .Data and origin must match")
return(TRUE)
}) # }}}