# FLPar - common structure for parameter matrices of various types.
# FLCore/R/FLPar.R
# Copyright 2003-2015 FLR Team. Distributed under the GPL 2 or later
# Maintainer: Iago Mosqueira, EC JRC G03
# Constructors {{{
# FLPar(array)
setMethod('FLPar', signature(object="array"),
function(object, params=letters[1:dim(object)[1]],
iter=seq(dim(object)[length(dim(object))]), units=rep('NA', dim(object)[1]),
dimnames= c(list(params=params), lapply(as.list(dim(object)[-c(1,
length(dim(object)))]), seq), list(iter=iter))) {
# if no dimnames, 1st is params, last is iter
if(!is.null(dimnames(object))) {
dimnames <- dimnames(object)
# if iter missing, add it
if(!any(names(dimnames) == "") & !'iter' %in% names(dimnames))
{
dimnames <- c(dimnames, list(iter=1))
object <- array(object, dimnames=dimnames,
dim=c(unlist(lapply(dimnames, length))))
}
# dimnames with no names, last one is iter ...
if(names(dimnames)[length(dimnames)] == "")
names(dimnames)[length(dimnames)] <- 'iter'
# ... others are dim*
if(any(names(dimnames) == ""))
names(dimnames)[names(dimnames) == ""] <-
paste('dim', seq(sum(names(dimnames) == "")))
# forcing iter to be last dim, all others as given
iterpos <- match(c('iter'), names(dimnames))
object <- aperm(object,
c(seq(1, length(dimnames))[!seq(1,length(dimnames)) %in% iterpos],
iterpos))
}
if(!is.numeric(object))
mode(object) <- 'double'
res <- array(object, dim=dim(object), dimnames=dimnames)
return(new('FLPar', res, units=units))
}
)
# FLPar(missing, iter, param)
setMethod('FLPar', signature(object="missing"),
function(..., params=character(1), iter=1, units='NA') {
args <- list(...)
# NO args, but iter and/or units
if(length(args) == 0) {
return(FLPar(array(as.numeric(NA), dim=c(length(params), iter),
dimnames=list(params=params, iter=seq(iter))), units=units))
}
# TREAT all inputs as vectors
args <- lapply(args, c)
# WARN if iter forces extending params
its <- unlist(lapply(args, length))
if(iter > 1 && any(its[its > 1] != iter))
warning("params with iterations will be extended to 'iter' length")
# CREATE dimnames, iter as max(length(args), iter)
dmns <- list(params=names(args), iter=seq(max(c(iter, its))))
dm <- unlist(lapply(dmns, length))
# EXTEND by iter
args <- lapply(args, rep, length.out=dm[2])
res <- array(do.call(rbind, args), dim=unname(dm), dimnames=dmns)
return(FLPar(res, units=units))
}
)
# FLPar(vector)
setMethod('FLPar', signature(object='vector'),
function(object, params= if(length(names(object))==length(object))
names(object) else letters[seq(length(object)/length(iter))], iter=1,
dimnames=list(params=params, iter=seq(iter)), byrow=FALSE,
units=rep('NA', dim(res)[1]))
{
# if length(iter) == 1, then expand
if(length(iter) == 1 && as.character(iter) != '1')
iter <- seq(iter)
res <- array(object, dim=unlist(lapply(dimnames, length)))
# FLPar(array)
return(FLPar(res, units=units, dimnames=dimnames))
}
)
# FLPar(FLPar)
setMethod('FLPar', signature('FLPar'),
function(object, dimnames=attr(object, 'dimnames'), params=dimnames$params,
iter=dimnames$iter, units=object@units, newDim="missing")
{
# get iter as vector if single number given
if(!missing(iter) && length(iter) == 1 && ac(iter) != '1')
iter <- ac(seq(as.numeric(iter)))
dimnames$params <- params
dimnames$iter <- ac(iter)
res <- FLPar(as.numeric(NA), dimnames=dimnames, units=units)
# select target dimnames and change names for '[<-'
dimnames <- dimnames(object)
names(dimnames) <- letters[seq(9,length=length(dimnames))]
res2=do.call('[<-', c(list(res), dimnames, list(value=object)))
if (missing(newDim))
return(res2)
dimnames <- dimnames(res2)
ord <- length(dimnames)
ord <- c(1:(ord-1),ord+1:length(newDim),ord)
dimnames[names(newDim)] <- newDim
res3 <- FLPar(rep(c(res2), length(unlist(newDim))),
dimnames=dimnames[ord],units=units)
return(res3)
}
) # }}}
# [ {{{
#' @rdname Extract
#' @aliases [,FLPar,ANY,ANY,ANY-method
setMethod('[', signature(x='FLPar'),
function(x, i, j, k, l, m, n, ..., drop=FALSE) {
dx <- lapply(as.list(dim(x)), seq_len)
names(dx) <- letters[seq(9, length=length(dx))]
# EXTRACT non-standard attributes
attrs <- attributes(x)
attrs <- attrs[!names(attrs) %in% c("dim", "dimnames", "units", "class")]
ldx <- length(dim(x))
# PARSE dims
for(ds in names(dx)) {
# MISSING arg
if(!do.call(missing, list(x=ds)))
dx[[ds]] <- get(ds)
}
if(drop) {
return(do.call('[', c(list(x=x@.Data), dx, list(drop=TRUE))))
}
res <- new(class(x), do.call('[', c(list(x=x@.Data), dx, list(drop=FALSE))))
if(!missing(i))
units(res) <- units(x)[ifelse(is.numeric(i), i, match(i, dimnames(x)$params))]
else
units(res) <- units(x)
# Add attributes not in standard object
if(length(attrs) > 0) {
for(i in names(attrs)) {
attr(res, i) <- attrs[[i]]
}
}
return(res)
}
)
#' @rdname Extract
#' @aliases [,FLPar,array,missing,missing-method
setMethod('[', signature(x='FLPar', i='array', j='missing', drop='missing'),
function(x, i) {
return(x@.Data[i])
}
) # }}}
# [<- {{{
#' @rdname Extract
#' @aliases [<-,FLPar,ANY,ANY,ANY-method
setMethod("[<-", signature(x="FLPar", value="ANY"),
function(x, i, j, k, l, m, n, ..., value)
{
# SUBSET on i if array
if(!missing(i) && is.array(i))
{
x@.Data[i] <- value
return(x)
}
# EXTRACT non-standard attributes
attrs <- attributes(x)
attrs <- attrs[!names(attrs) %in% c("dim", "dimnames", "units", "class")]
dx <- lapply(as.list(dim(x)), seq_len)
names(dx) <- letters[seq(9, length=length(dx))]
for(ds in names(dx)) {
# MISSING arg
if(!do.call(missing, list(x=ds)))
dx[[ds]] <- get(ds)
}
res <- new(class(x), do.call('[<-', c(list(x=x@.Data), dx, list(value=value))))
# Add attributes not in standard object
if(length(attrs) > 0) {
for(i in names(attrs)) {
attr(res, i) <- attrs[[i]]
}
}
return(res)
}
) # }}}
# iter, iter<- {{{
setMethod("iter", signature(obj="FLPar"),
function(obj, iter) {
if(dim(obj)[length(dim(obj))] == 1)
return(obj)
else {
lst <- list(x=obj, pos=iter)
names(lst) <- c('x', letters[8+length(dim(obj))])
return(do.call('[', lst))
}
}
)
setMethod("iter<-", signature(object="FLPar", value="FLPar"),
function(object, iter, value)
{
lst <- list(x=object, pos=iter, value=value)
names(lst) <- c('x', letters[8+length(dim(object))], 'value')
object <- do.call('[<-', lst)
return(object)
}
)
setMethod("iter<-", signature(object="FLPar", value="numeric"),
function(object, iter, value)
{
lst <- list(x=object, pos=iter, value=value)
names(lst) <- c('x', letters[8+length(dim(object))], 'value')
object <- do.call('[<-', lst)
return(object)
}
)
# }}}
# summary {{{
#' @rdname summary-methods
#' @aliases summary,FLPar-method
setMethod('summary', signature(object='FLPar'),
function(object, title=TRUE, ...) {
if(title)
cat("An object of class \"", class(object), "\"\n\n", sep="")
if(dim(object)[length(dim(object))] == 1)
return(object)
else
return(apply(object@.Data, seq(dim(object))[-length(dim(object))], summary))
}
) # }}}
# units {{{
#' @rdname units-FLCore
setMethod("units", signature(x="FLPar"),
function(x)
return(x@units)
) # }}}
# units<- {{{
#' @rdname units-FLCore
setMethod("units<-", signature(x="FLPar", value="character"),
function(x, value) {
x@units <- value
return(x)
}
) # }}}
# as.data.frame {{{
setMethod("as.data.frame", signature(x="FLPar"),
function(x, row.names='col', optional=FALSE, drop=FALSE) {
res <- as(x, 'data.frame')
if(drop) {
idx <- names(x)[dim(x) > 1]
res <- res[, c(idx, 'data')]
}
return(res)
}
) # }}}
# iterMedians, Means & Vars {{{
#' @rdname dimSummaries
setMethod("iterMeans", "FLPar",
function(x, na.rm=TRUE) {
dim <- seq(length=length(dim(x)))
apply(x, dim[-length(dim)], mean, na.rm=na.rm)
}
)
#' @rdname dimSummaries
setMethod("iterMedians", "FLPar",
function(x, na.rm=TRUE) {
dim <- seq(length=length(dim(x)))
apply(x, dim[-length(dim)], median, na.rm=na.rm)
}
)
#' @rdname dimSummaries
setMethod("iterVars", "FLPar",
function(x, na.rm=TRUE) {
dim <- seq(length=length(dim(x)))
apply(x, dim[-length(dim)], var, na.rm=na.rm)
}
)
#' @rdname dimSummaries
setMethod("iterSums", "FLPar",
function(x, na.rm=TRUE) {
dim <- seq(length=length(dim(x)))
apply(x, dim[-length(dim)], sum, na.rm=na.rm)
}
)
# }}}
# coerce {{{
setAs('FLPar', 'numeric',
function(from)
{
res <- as.vector(from[1,])
names(res) <- dimnames(from)$param
return(res)
}
)
setAs("FLPar", "list",
function(from) {
lst <- split(from@.Data, 1:nrow(from))
names(lst) <- dimnames(from)[[1]]
return(lst)
}
)
setAs('FLQuant', 'FLPar',
function(from)
{
# check quant(from) == 'params'
if(quant(from) != 'params')
stop("'quant' in FLQuant must be 'params'")
# extract array with dims of length < 1 collapsed
res <- from@.Data[,,,,,,drop=TRUE]
res <- FLPar(res)
if(validObject(res))
return(res)
else
stop("created object is not valid, please check input")
}
)
setAs('FLPar', 'FLQuant',
function(from)
{
# extract array
data <- from@.Data
# and names
names <- names(dimnames(data))
# output FLQuant
res <- FLQuant(quant='params', units=ifelse(all(units(from) == 'NA'),
'NA', paste(units(from), collapse='_')))
# reshape data for FLQuant dimnames
idx <- match(names(res), names)
idx <- idx[!is.na(idx)]
data <- aperm(data, idx)
# get dim and dimnames for FLQuant
idx <- names(res) %in% names(dimnames(data))
dim <- rep(1,6)
dim[idx] <- dim(data)
dnames <- dimnames(res)
dnames[idx] <- dimnames(data)
res@.Data <- array(data, dim=dim, dimnames=dnames)
return(res)
}
)
# }}}
# propagate {{{
setMethod("propagate", signature(object="FLPar"),
function(object, iter, fill.iter=TRUE) {
# RETURN object if iter == iters
dob <- dim(object)
if(iter == dob[length(dob)])
return(object)
# dimnames of input object
dnames <- dimnames(object)
dnames$iter <- seq(iter)
# CREATE new object
res <- FLPar(NA, dimnames=dnames)
# PLACE content in iters(object)
res[,,seq(dob[length(dob)])] <- object
# fill.iter
if(fill.iter == TRUE)
{
args <- list(x=res, iter=seq(iter)[-1], value=object)
names(args)[2] <- letters[seq(9,
length=length(dim(res)))][names(dimnames(res))=='iter']
res <- do.call('[<-', args)
}
return(res)
}
) # }}}
# dims {{{
setMethod("dims", signature(obj="FLPar"),
# Return a list with different parameters
function(obj, ...) {
dimnames(obj)
names(obj)
iter <- length(dimnames(obj)$iter)
params <- dimnames(obj)$params
return(list(iter=iter, params=params))
}
) # }}}
# names {{{
#' @rdname names
#' @aliases names,FLPar-method
setMethod("names", signature(x="FLPar"),
function(x)
names(dimnames(x))
)
# }}}
# names<- {{{
#' @rdname names
#' @aliases names<-,FLPar,character-method
setMethod("names<-", signature(x="FLPar", value="character"),
function(x, value)
{
# last dim must be 'iter', as in validFLPar
if(value[length(value)] != 'iter')
stop("last dimension must be named 'iter'")
names(dimnames(x)) <- value
return(x)
}
)
# }}}
# show {{{
setMethod("show", signature(object="FLPar"),
function(object) {
ndim <- length(dim(object))
cat("An object of class \"", as.character(class(object)), "\"\n", sep="")
if(dim(object)[ndim] != 1)
cat("iters: ", dim(object)[ndim],"\n\n")
if(dim(object)[ndim] > 1)
{
v1 <- apply(object@.Data, 1:(ndim-1), median, na.rm=TRUE)
v2 <- apply(object@.Data, 1:(ndim-1), mad, na.rm=TRUE)
v3 <- paste(format(v1,digits=5),"(", format(v2, digits=3), ")", sep="")
}
else
v3 <- format(object@.Data, digits=3)
print(array(v3, dim=dim(object)[1:(ndim-1)], dimnames=dimnames(object)[1:(ndim-1)]),
quote=FALSE)
cat("units: ", object@units, "\n")
}
) # }}}
# print {{{
setMethod("print", signature(x="FLPar"),
function(x, reduced=FALSE){
if(reduced) {
if(length(dimnames(x)[['iter']]) == 1) {
print(t(x@.Data), digits=3)
} else {
v1 <- apply(x@.Data, 1, median, na.rm=TRUE)
v2 <- apply(x@.Data, 1, mad, na.rm=TRUE)
v3 <- paste(format(v1, digits=3),"(", format(v2, digits=3), ")", sep="")
names(v3) <- names(v1)
print(v3, quote=FALSE)
}
} else {
show(x)
invisible(x)
}
}
) # }}}
# Arith {{{
#' @rdname Arith-methods
setMethod("Arith", ## "+", "-", "*", "^", "%%", "%/%", "/"
signature(e1 = "FLPar", e2 = "FLPar"),
function(e1, e2)
{
return(new('FLPar', callGeneric(e1@.Data, e2@.Data)))
}
)
#' @rdname Arith-methods
#' @examples
#' # FLQuant and FLPar
#' flq / flp
setMethod("Arith", signature(e1 = "FLArray", e2 = "FLPar"),
function(e1, e2) {
# BUG: USING %op%
op <- as.character(get('.Generic'))
return(do.call(paste0("%", op, "%"), list(e1, e2)))
# objects dims
d1 <- dim(e1)
d2 <- dim(e2)
l2 <- length(d2)
n1 <- names(dimnames(e1))
n2 <- names(dimnames(e2))
op <- as.character(get('.Generic'))
uoms <- uom(op, units(e1), units(e2))
# iter of output
it <- max(d1[6], d2[l2])
# dims of length > 1 (except iter), must be in FLArray
if(any(!(n2[-l2][d2[-l2] > 1]) %in% (n1[-6][d1[-6] > 1])))
stop(paste("FLPar object cannot have dimensions of length > 1 not in",
ac(class(e1))))
# reshape FLPar
m2 <- unique(c(match(n2[-length(d2)], n1[-6]), seq(1, 6)))
m2 <- m2[!is.na(m2)]
e2 <- aperm(array(e2, dim=d1[m2]), m2)
# iters from FLQ
if(d1[6] >= d2[l2]) {
return(new(class(e1), array(callGeneric(e1@.Data, e2), dim=d1,
dimnames=dimnames(e1)), units=uoms))
} else {
return(new(class(e1), array(callGeneric(array(e1@.Data,
dim=c(c(d1[-6], it))), array(e2, dim=c(d1[-6], it))), dim=c(d1[-6], it),
dimnames=c(dimnames(e1)[-6], list(iter=seq(it)))),
units=uoms))
}
}
)
#' @rdname Arith-methods
setMethod("Arith", signature(e1 = "FLPar", e2 = "FLArray"),
function(e1, e2) {
# BUG: USING %op%
op <- as.character(get('.Generic'))
return(do.call(paste0("%", op, "%"), list(e1, e2)))
# objects dims
d1 <- dim(e1)
d2 <- dim(e2)
l1 <- length(d1)
n1 <- names(dimnames(e1))
n2 <- names(dimnames(e2))
op <- as.character(get('.Generic'))
uoms <- uom(op, units(e1), units(e2))
# iter of output
it <- max(d1[l1], d1[6])
# dims of length > 1 (except iter), must be in FLArray
if(any(!(n1[-l1][d1[-l1] > 1]) %in% (n2[-6][d2[-6] > 1])))
stop(paste("FLPar object cannot have dimensions of length > 1 not in",
ac(class(e2))))
# reshape FLPar
m1 <- unique(c(match(n1[-length(d1)], n2[-6]), seq(1, 6)))
m1 <- m1[!is.na(m1)]
e1 <- aperm(array(e1, dim=d2[m1]), m1)
# iters from FLQ
if(d2[6] >= d1[l1]) {
return(new(class(e2), array(callGeneric(e1, e2@.Data), dim=d2,
dimnames=dimnames(e2)), units=uoms))
} else {
return(new(class(e2), array(callGeneric(e1, e2@.Data), dim=c(d2[-6], it),
dimnames=c(dimnames(e2)[-6], list(iter=seq(it)))),
units=uoms))
}
}
)
# }}}
# Compare {{{
setMethod("Compare", signature(e1 = "FLPar", e2 = "FLArray"),
function(e1, e2) {
return(c(callGeneric(c(e1), c(e2))))
})
setMethod("Compare", signature(e1 = "FLArray", e2 = "FLPar"),
function(e1, e2) {
return(c(callGeneric(c(e1), c(e2))))
})
# }}}
# ab {{{
setMethod('ab', signature(x='FLPar', model='character'),
function(x, model, spr0=NULL)
{
# input params and default values
args <- c(as(x, 'list'), as.list(spr0))
names(args)[length(args)] <- "spr0"
args['model'] <- model
res <- do.call('abPars', args)
# get back c and d and spr0
cd <- args[c('c', 'd', 'spr0')]
res <- c(res, unlist(cd[!unlist(lapply(cd, is.null))]))
return(do.call('FLPar', res))
})
setMethod('ab', signature(x='FLPar', model='formula'),
function(x, model, spr0=NULL)
{
model <- SRModelName(model)
if(is.null(model))
stop("model provided has not been identified")
else
return(ab(x, model))
})# }}}
# sv {{{
setMethod('sv', signature(x='FLPar', model='character'),
function(x, model, spr0)
{
# input params and default values
args <- c(as(x, 'list'), as.list(spr0))
names(args)[length(args)] <- "spr0"
args['model'] <- model
res <- do.call('svPars', args)
# get back c and d
cd <- args[c('c', 'd')]
res <- c(res, unlist(cd[!unlist(lapply(cd, is.null))]))
return(do.call('FLPar', res))
})
setMethod('sv', signature(x='FLPar', model='formula'),
function(x, model, spr0)
{
model <- SRModelName(model)
if(is.null(model))
stop("model provided has not been identified")
else
return(sv(x, model=model, spr0=spr0))
})# }}}
# sweep {{{
#' @rdname sweep-methods
setMethod('sweep', signature(x='FLPar'),
function(x, MARGIN, STATS, FUN, check.margin=TRUE, ...)
{
res <- callNextMethod()
do.call(class(x), list(res, units=units(x)))
}
) # }}}
# apply {{{
#' @rdname apply-methods
setMethod('apply', signature(X='FLPar'),
function(X, MARGIN, FUN, ...)
{
res <- callNextMethod()
do.call(class(X), list(res, units=units(X)))
}
) # }}}
# rbind2 {{{
setMethod('rbind2', signature(x='FLPar', y='FLPar'),
function(x, y, ...) {
args <- c(list(x=x, y=y), list(...))
# FLPars dimensions and dimnames
dimar <- lapply(args, dim)
nrow <- sum(unlist(lapply(dimar, `[`, 1)))
dnms <- lapply(args, dimnames)
# CHECK all have same length(dims)
if(length(unique(unlist(lapply(dimar, length)))) != 1)
stop("FLPar object to rbind must share number of dimensions")
# CHECK all have same dim[-1]
dms <- apply(matrix(unlist(dimar), byrow=TRUE, nrow=length(args)), 2,
function(x) length(unique(x)))
if(any(dms[-1] != 1))
stop("FLPar object to rbind must share number of dimensions except params")
# CHECK names(dimnames) match
if(!all.equal(Reduce(intersect, lapply(dnms, names)), names(dnms[[1]])))
stop("Names of dimnames must match")
# TODO
# CHECK dimnames[-c(1, iter)] match
#onms <- lapply(dnms, `[`, -c(1, length(dimar[[1]])))
#for(i in names(onms[[1]])) {
# if(length(unique(unlist(lapply(onms, `[[`, i)))) > 1)
# stop(paste0("dimnames across objects must match for dimension '", i, "'"))
#}
# params names
nargs <- lapply(lapply(args, dimnames), `[`, 1)
# aperm to join by row
idx <- c(seq(2, length(dimar[[1]])), 1)
pargs <- lapply(args, aperm, idx)
# then re-aperm
idx <- c(length(dimar[[1]]), seq(1, length(dimar[[1]]) - 1))
res <- aperm(array(unlist(pargs), dim=c(dimar[[1]][-1], nrow)), idx)
# dimnames
dimnames(res) <- c(list(params=unlist(nargs, use.names=FALSE)), dimnames(x)[-1])
res <- FLPar(res, units=units(args[[1]]))
# keep names of x
names(res) <- names(x)
return(res)
}
) # }}}
# cbind2 {{{
setMethod('cbind2', signature(x='FLPar', y='FLPar'),
function(x, y, ...) {
args <- c(list(x=x, y=y), list(...))
idx <- unlist(lapply(args, is, 'FLPar'))
if(!all(idx))
stop("input objects must all be of class 'FLPar'")
res <- args[[1]]@.Data
if(length(args) > 1)
for (i in seq(length(args))[-1])
res <- cbind(res, args[[i]]@.Data)
# dimnames
names(dimnames(res)) <- names(dimnames(args[[1]]))
# correct for iter dimnames
dimnames(res)$iter <- seq(length(dimnames(res)$iter))
if(any(unlist(lapply(dimnames(res), function(x) any((x==x[1])[-1])))))
warning("Repeated dimnames in output FLPar")
return(FLPar(res, units=units(args[[1]])))
}
) # }}}
# rlnorm {{{
setMethod("rlnorm", signature(n='numeric', meanlog="FLPar", sdlog="FLPar"),
function(n=1, meanlog, sdlog) {
if(all(dim(meanlog) != dim(sdlog)))
stop("dims of meanlog and sdlog must be equal")
lastdim <- length(dim(meanlog))
FLPar(array(rlnorm(prod(dim(meanlog)[-lastdim])*n,
rep(iter(meanlog, 1)[drop=TRUE], n),
rep(iter(sdlog, 1)[drop=TRUE],n)),
dim=c(dim(meanlog)[-lastdim], n)),
dimnames=c(dimnames(meanlog)[-lastdim], list(iter=seq(n))))
}
)
setMethod("rlnorm", signature(n='numeric', meanlog="FLPar", sdlog="numeric"),
function(n=1, meanlog, sdlog) {
rlnorm(n, meanlog, FLPar(sdlog, dimnames=dimnames(meanlog)))
}
)
setMethod("rlnorm", signature(n='numeric', meanlog="numeric", sdlog="FLPar"),
function(n=1, meanlog, sdlog)
rlnorm(n, FLPar(meanlog, dimnames=dimnames(sdlog)), sdlog)
)
setMethod("rlnorm", signature(n='numeric', meanlog="FLPar", sdlog="missing"),
function(n=1, meanlog, sdlog)
rlnorm(n, meanlog, 1)
)
setMethod("rlnorm", signature(n='numeric', meanlog="missing", sdlog="FLPar"),
function(n=1, meanlog, sdlog)
rlnorm(n, 0, sdlog)
)
setMethod("rlnorm", signature(n='FLPar', meanlog="ANY", sdlog="ANY"),
function(n, meanlog=0, sdlog=1) {
FLPar(rlnorm(length(n), meanlog, sdlog), dimnames=dimnames(n))
}
)
# }}}
# rnorm {{{
setMethod("rnorm", signature(n='numeric', mean="FLPar", sd="FLPar"),
function(n=1, mean, sd) {
if(all(dim(mean) != dim(sd)))
stop("dims of mean and sd must be equal")
lastdim <- length(dim(mean))
FLPar(array(rnorm(prod(dim(mean)[-lastdim])*n,
rep(iter(mean, 1)[drop=TRUE], n),
rep(iter(sd, 1)[drop=TRUE],n)),
dim=c(dim(mean)[-lastdim], n)),
dimnames=c(dimnames(mean)[-lastdim], list(iter=seq(n))))
}
)
setMethod("rnorm", signature(n='numeric', mean="FLPar", sd="numeric"),
function(n=1, mean, sd) {
rnorm(n, mean, FLPar(sd, dimnames=dimnames(mean)))
}
)
setMethod("rnorm", signature(n='numeric', mean="numeric", sd="FLPar"),
function(n=1, mean, sd)
rnorm(n, FLPar(mean, dimnames=dimnames(sd)), sd)
)
setMethod("rnorm", signature(n='numeric', mean="FLPar", sd="missing"),
function(n=1, mean, sd)
rnorm(n, mean, 1)
)
setMethod("rnorm", signature(n='numeric', mean="missing", sd="FLPar"),
function(n=1, mean, sd)
rnorm(n, 0, sd)
)
setMethod("rnorm", signature(n='FLPar', mean="ANY", sd="ANY"),
function(n, mean=0, sd=1) {
FLPar(rnorm(length(n), mean, sd), dimnames=dimnames(n))
}
)
# }}}
# mvrnorm {{{
setMethod("mvrnorm", signature(n="numeric", mu="FLPar", Sigma="matrix",
tol="missing", empirical="missing", EISPACK="missing"),
function(n, mu, Sigma) {
dm <- dim(mu)
dnm <- dimnames(mu)
# Check that params second dim is "iter"
if(names(dnm)[2]!="iter")
stop("To apply this method params must have 2 dimensions only and the
second has to be \"iter\".")
# Check dims
if(dm[2] > 1)
stop("mu FLPar cannot have iterations")
res <- do.call("mvrnorm", list(mu=c(mu), Sigma=Sigma, n=n))
if(n>1)
res <- t(res)
else
res <- matrix(res, ncol=1)
dnm$iter <- 1:n
dimnames(res) <- dnm
res <- FLPar(res)
units(res) <- units(mu)
return(res)
}
) # }}}
# model.frame {{{
setMethod("model.frame", signature(formula="FLPar"),
function(formula, ...) {
dmn <- dim(formula)
# extract array
res <- formula@.Data
# shape into matrix (no. params, all other dims)
dim(res) <- c(dmn[1], prod(dmn[-1]))
# rotate and data.frame
res <- as.data.frame(t(res))
# add params names
names(res) <- dimnames(formula)[[1]]
# add other cols
res <- cbind(res, expand.grid(dimnames(formula)[-1]))
# make year numeric
if("year" %in% names(res))
res$year <- as.numeric(res$year)
return(res)
}
) # }}}
# $ {{{
#' @rdname Extract
#' @aliases $,FLPar-method
setMethod('$', signature(x='FLPar'),
function(x, name) {
return(x[name,])
}
)
#' @rdname Extract
#' @aliases $<-,FLPar,ANY-method
setReplaceMethod("$", signature(x="FLPar", value="ANY"),
function(x, name, value) {
# SUBSTITUTE existing param
if(name %in% dimnames(x)$params) {
x[name,] <- value
# or ADD new one
} else {
value <- FLPar(value)
dimnames(value)$params <- name
x <- rbind(x, value)
}
return(x)
}
)
# }}}
# expand {{{
setMethod('expand', signature(x='FLPar'),
function(x, ...) {
args <- list(...)
dnx <- dimnames(x)
# dimension names
nargs <- names(args)
qnames <- names(dnx)
# check input names match dimnames
if(!all(nargs %in% qnames))
stop(paste("Wrong dimension name provided: ", nargs[!nargs%in%qnames]))
# turn into characters
select <- lapply(args, as.character)
# match specified dimensions and dimnames
dimnames <- dnx
# new dimnames
dimnames[names(select)] <- select
# output object
res <- new(class(x), array(as.numeric(NA), dimnames=dimnames,
dim=unlist(lapply(dimnames, length))), units=units(x))
# assigment list by position to avoid "" dimnames
dnx <- setNames(lapply(as.list(dim(x)), seq),
c('i', 'j', 'k', 'l', 'm', 'n')[seq(length(dim(res)))])
return(do.call('[<-', c(list(x=res, value=x), dnx)))
}
) # }}}
# window {{{
setMethod("window", signature(x="FLPar"),
function(x, start=as.numeric(dimnames(x)$year[1]),
end=as.numeric(dimnames(x)$year[length(dimnames(x)$year)]), extend=TRUE,
frequency=1) {
#
if(!"year" %in% names(x))
stop("window can only be called to objects with a 'year' dimension")
# get original min and max
yrs <- dimnames(x)$year
min <- as.numeric(yrs[1])
max <- as.numeric(yrs[length(yrs)])
pos <- match("year", names(x))
# if extend=FALSE and end/start ask for it, error
if(!extend && (start < min | end > max))
stop("FLPar to be extended but extend=FALSE")
# if extend is a number, added to end
if(is.numeric(extend))
if (missing(end))
end <- max + extend
else
stop("'extend' is numeric and 'end' provided, don't know what to do")
# construct new FLPar
dnames <- dimnames(x)
dnames[[pos]] <- seq(start, end, by=frequency)
res <- do.call(class(x), list(NA, units=units(x), dimnames=dnames))
# add data for matching years
dnames <- dnames[pos]
names(dnames) <- c('i', 'j', 'k', 'l', 'm', 'n')[pos]
do.call('[<-', c(list(x=res, value=x), dimnames))
}
) # }}}
# divide {{{
#' @example
#' divide(FLPar(FMSY=0.21, BMSY=120012), names=c(F="FMSY", B="BMSY"))
setMethod("divide", signature(object="FLPar"),
function(object, dim=1, names=setNames(nm=dimnames(object)[[dim]])) {
return(FLPars(lapply(names, function(x) object[x,])))
}
)
# }}}
# combine {{{
setMethod("combine", signature(x="FLPar", y="FLPar"),
function(x, y, ..., check=FALSE) {
args <- c(list(x, y), list(...))
# FIND iter dim
dis <- dim(x)
dit <- length(dis)
dmns <- dimnames(x)
its <- sum(unlist(lapply(args, function(i) dim(i)[dit])))
# NEW array & FLPar
arr <- array(unlist(lapply(args, c)), dim=c(dis[-dit], its))
res <- FLPar(arr, dimnames=c(dmns[-length(dis)], list(iter=seq(dim(arr)[dit]))),
units=units(x))
return(res)
}
)
# }}}
# FLParPoint {{{
#' @examples
#' x <- FLPar(a=runif(500, 1, 3), b=rlnorm(500, 0.4, 0.9), c=9, d=runif(500))
#' FLParPoint(x)
#' iter(FLParPoint(x), 'median')
#' iter(FLParPoint(x), 'uppq')
#' iter(FLParPoint(x, probs=c(0.10, 0.90)), 'uppq')
FLParPoint <- function(x, probs=c(0.25, 0.75)) {
dmx <- dim(x)
dmi <- seq(length(dmx))[-length(dmx)]
res <- cbind(
# mean
apply(x, dmi, mean, na.rm=TRUE),
# median
apply(x, dmi, median, na.rm=TRUE),
# var
apply(x, dmi, var, na.rm=TRUE),
# lowq
apply(x, dmi, quantile, probs[1], na.rm=TRUE),
# uppq
apply(x, dmi, quantile, probs[2], na.rm=TRUE))
dimnames(res)$iter <- c("mean","median","var","lowq","uppq")
return(res)
}
# }}}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.