Rev 8408 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
### Fit a general nonlinear regression model with correlated and/or### heteroscedastic errors###### Copyright 2007-2026 The R Core team### Copyright 1997-2003 Jose C. Pinheiro,### Douglas M. Bates <bates@stat.wisc.edu>## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## A copy of the GNU General Public License is available at# http://www.r-project.org/Licenses/#gnls <- function(model,data = sys.frame(sys.parent()),params,start,correlation = NULL,weights = NULL,subset,na.action = na.fail,naPattern,control = list(),verbose= FALSE){finiteDiffGrad <-function(model, data, pars){dframe <- data.frame(data, pars)base <- eval(model, dframe)nm <- colnames(pars)grad <- array(base, c(length(base), length(nm)), list(NULL, nm))ssize <- sqrt(.Machine$double.eps)for (i in nm) {diff <- pp <- pars[ , i]diff[pp == 0] <- ssizediff[pp != 0] <- pp[pp != 0] * ssizedframe[[i]] <- pp + diffgrad[ , i] <- (base - eval(model, dframe))/diffdframe[[i]] <- pp}grad}## keeping the callCall <- match.call()## assigning a new name to the "object" argumentform <- model## control parameterscontrolvals <- gnlsControl()if (!missing(control)) {controlvals[names(control)] <- control}#### checking arguments##if (!inherits(form, "formula"))stop("'object' must be a formula")if (length(form)!=3)stop("model formula must be of the form \"resp ~ pred\"")## if (length(attr(terms(form), "offset")))## stop("offset() terms are not supported")#### checking if self-starting formula is given##if (missing(start)) {if (is.call(form[[3]]) && !is.null(attr(eval(form[[3]][[1]]), "initial"))) {nlsCall <- Call[c("","model","data")]nlsCall[[1]] <- quote(stats::nls)names(nlsCall)[2] <- "formula"## checking if "data" is not equal to sys.frame(sys.parent())if (is.null(dim(data))) {stop("'data' must be given explicitly to use 'nls' to get initial estimates")}start <- coef(eval.parent(nlsCall))} else {stop("no initial values for model parameters")}} else {start <- unlist(start)}gnlsModel <- call("-", form[[2]], form[[3]])#### save writing list(...) when only one element##if (missing(params)) {if (is.null(pNams <- names(start))) {stop("starting estimates must have names when 'params' is missing")}params <- list(formula(paste(paste(pNams, collapse = "+"), "1", sep = "~")))}else if (!is.list(params))params <- list(params)params <- unlist(lapply(params, function(pp) {if (is.name(pp[[2]])) {list(pp)} else {## multiple parameters on left hand sideeval(parse(text = paste("list(",paste(paste(all.vars(pp[[2]]), deparse(pp[[3]]), sep = "~"),collapse = ","),")")))}}), recursive=FALSE)pnames <- character(length(params))for (i in seq_along(params)) {this <- eval(params[[i]])if (!inherits(this, "formula"))stop ("'params' must be a formula or list of formulae")if (length(this) != 3)stop ("formulae in 'params' must be of the form \"parameter ~ expr\"")if (!is.name(this[[2]]))stop ("formulae in 'params' must be of the form \"parameter ~ expr\"")pnames[i] <- as.character(this[[2]])}names(params) <- pnames## check if correlation is present and has groupsgroups <- if (!is.null(correlation)) getGroupsFormula(correlation) # else NULL# if (!is.null(correlation)) {# groups <- getGroupsFormula(correlation, asList = TRUE)# if (!is.null(groups)) {# if (length(groups) > 1) {# stop("Only single level of grouping allowed")# }# groups <- groups[[1]]# } else {# if (inherits(data, "groupedData")) { # will use as groups# groups <- getGroupsFormula(data, asList = TRUE)# if (length(groups) > 1) { # ignore it# groups <- NULL# } else {# groups <- groups[[1]]# attr(correlation, "formula") <-# eval(parse(text = paste("~",# deparse(getCovariateFormula(formula(correlation))[[2]]),# "|", deparse(groups[[2]]))))# }# }# }# } else groups <- NULL## create an gnls structure containing the correlation and weightsgnlsSt <- gnlsStruct(corStruct = correlation, varStruct = varFunc(weights))## extract a data frame with enough information to evaluate## form, params, random, groups, correlation, and weightsmfArgs <- list(formula = asOneFormula(formula(gnlsSt), form, params,groups, omit = c(pnames, "pi")),data = data, na.action = na.action)if (!missing(subset)) {mfArgs[["subset"]] <- asOneSidedFormula(Call[["subset"]])[[2]]}mfArgs$drop.unused.levels <- TRUEdataMod <- do.call("model.frame", mfArgs)origOrder <- row.names(dataMod) # preserve the original order#### Evaluating the groups expression, if needed##if (!is.null(groups)) {## sort the model.frame by groups and get the matrices and parameters## used in the estimation procedures## always use innermost level of groupinggroups <- eval(substitute( ~1 | GRP, list(GRP = groups[[2]])))grps <- getGroups(dataMod, groups,level = length(getGroupsFormula(groups, asList = TRUE)))## ordering data by groupsord <- order(grps)grps <- grps[ord]dataMod <- dataMod[ord, ,drop = FALSE]## revOrder <- match(origOrder, row.names(dataMod)) # putting in orig. order} else grps <- NULLN <- dim(dataMod)[1] # number of observations#### evaluating the naPattern expression, if any##naPat <- if (missing(naPattern)) rep(TRUE, N)else as.logical(eval(asOneSidedFormula(naPattern)[[2]], dataMod))origOrderShrunk <- origOrder[naPat]dataModShrunk <- dataMod[naPat, , drop=FALSE]yShrunk <- eval(form[[2]], dataModShrunk)grpShrunk <-if (!is.null(groups)) {## ordShrunk <- ord[naPat]revOrderShrunk <- match(origOrderShrunk, row.names(dataModShrunk))grps[naPat]} # else NULL#### defining list with parameter information##contr <- list()plist <- vector("list", length(pnames))names(plist) <- pnamesfor (nm in pnames) {rhs <- params[[nm]][[3]]plist[[nm]] <-if(identical(rhs, 1) || identical(rhs, 1L)) ## constant RHSTRUEelse {form1s <- asOneSidedFormula(rhs).X <- model.frame(form1s, dataModShrunk)## keeping the contrast matrices for later use in predictauxContr <- lapply(.X, function(el) if (is.factor(el)) contrasts(el))contr <- c(contr, auxContr[!vapply(auxContr, is.null, NA) &is.na(match(names(auxContr), names(contr)))])model.matrix(form1s, .X)}}#### Params effects names##pn <- character(0)currPos <- 0parAssign <- list()for(nm in pnames) {if (is.logical(p <- plist[[nm]])) {currPos <- currPos + 1currVal <- list(currPos)pn <- c(pn, nm)names(currVal) <- nmparAssign <- c(parAssign, currVal)} else {currVal <- attr(p, "assign")fTerms <- terms(asOneSidedFormula(params[[nm]][[3]]), data=data)namTerms <- attr(fTerms, "term.labels")if (attr(fTerms, "intercept") > 0) {namTerms <- c("(Intercept)", namTerms)}namTerms <- factor(currVal, labels = namTerms)currVal <- split(order(currVal), namTerms)names(currVal) <- paste(nm, names(currVal), sep = ".")parAssign <- c(parAssign, lapply(currVal,function(el, currPos) {el + currPos}, currPos = currPos))currPos <- currPos + length(unlist(currVal))pn <- c(pn, paste(nm, colnames(p), sep = "."))}}pLen <- length(pn)if (length(start) != pLen)stop(sprintf(ngettext(length(start),"supplied %d starting value, need %d","supplied %d starting values, need %d"),length(start), pLen), domain = NA)spar <- startnames(spar) <- pnNReal <- sum(naPat)#### Creating the params map##pmap <- list()n1 <- 1for(nm in pnames) {if (is.logical(p <- plist[[nm]])) {pmap[[nm]] <- n1n1 <- n1 + 1} else {pmap[[nm]] <- n1:(n1+ncol(p) - 1)n1 <- n1 + ncol(p)}}#### defining the nlFrame, i.e., nlEnv, an environment in R :##nlEnv <- list2env(list(model = gnlsModel,data = dataMod,plist = plist,beta = as.vector(spar),X = array(0, c(NReal, pLen), list(NULL, pn)),pmap = pmap,N = NReal,naPat = naPat,.parameters = c("beta"),finiteDiffGrad = finiteDiffGrad))modelExpression <- ~ {pars <- getParsGnls(plist, pmap, beta, N)res <- eval(model, data.frame(data, pars))if (!length(grad <- attr(res, "gradient"))) {grad <- finiteDiffGrad(model, data, pars)[naPat, , drop = FALSE]} else {grad <- grad[naPat, , drop = FALSE]}res <- res[naPat]for (nm in names(plist)) {gradnm <- grad[, nm]X[, pmap[[nm]]] <-if(is.logical(p <- plist[[nm]])) gradnm else gradnm * p}result <- c(X, res)result[is.na(result)] <- 0result}modelResid <- ~eval(model, data.frame(data,getParsGnls(plist, pmap, beta, N)))[naPat]w <- eval(modelResid[[2]], envir = nlEnv)## creating the condensed linear model## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative SolutionsfixedSigma <- controlvals$sigma > 0Dims <- list(p = pLen, N = NReal, REML = FALSE)attr(gnlsSt, "conLin") <-list(Xy = array(w, c(NReal, 1),list(row.names(dataModShrunk), deparse(form[[2]]))),dims = Dims, logLik = 0,## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionssigma=controlvals$sigma, auxSigma=0, fixedSigma=fixedSigma)## additional attributes of gnlsStattr(gnlsSt, "resp") <- yShrunkattr(gnlsSt, "model") <- modelResidattr(gnlsSt, "local") <- nlEnvattr(gnlsSt, "NReal") <- NReal## initializationgnlsSt <- Initialize(gnlsSt, dataModShrunk)parMap <- attr(gnlsSt, "pmap")numIter <- 0 # number of iterationsnlsSettings <- c(controlvals$nlsMaxIter, controlvals$minScale,controlvals$nlsTol, 0, 0, 0)nlModel <- nonlinModel(modelExpression, nlEnv)repeat {## alternating algorithmnumIter <- numIter + 1## GLS stepif (needUpdate(gnlsSt)) { # updating varying weightsgnlsSt <- update(gnlsSt, dataModShrunk)}if (length(oldPars <- coef(gnlsSt)) > 0) {if (controlvals$opt == "nlminb") {optRes <- nlminb(c(coef(gnlsSt)),function(gnlsPars) -logLik(gnlsSt, gnlsPars),control = list(trace = controlvals$msVerbose,iter.max = controlvals$msMaxIter))convIter <- optRes$iterations} else {optRes <- optim(c(coef(gnlsSt)),function(gnlsPars) -logLik(gnlsSt, gnlsPars),method = controlvals$optimMethod,control = list(trace = controlvals$msVerbose,maxit = controlvals$msMaxIter,reltol = if(numIter == 0) controlvals$msTolelse 100*.Machine$double.eps))convIter <- optRes$count[2]}aConv <- coef(gnlsSt) <- optRes$parif (verbose) {cat("\n**Iteration", numIter)cat("\n")cat("GLS step: Objective:", format(optRes$value))print(gnlsSt)}} else {aConv <- oldPars <- NULL}## NLS stepif (is.null(correlation)) {cF <- 1.0cD <- 1} else {cF <- corFactor(gnlsSt$corStruct)cD <- Dim(gnlsSt$corStruct)}if (is.null(weights)) {vW <- 1.0} else {vW <- varWeights(gnlsSt$varStruct)}work <- .C(fit_gnls,thetaNLS = as.double(spar),as.integer(unlist(Dims)),as.double(cF),as.double(vW),as.integer(unlist(cD)),settings = as.double(nlsSettings),additional = double(NReal),as.integer(!is.null(correlation)),as.integer(!is.null(weights)),nlModel,NAOK = TRUE)[c("thetaNLS", "settings", "additional")]if (work$settings[4] == 1) {## convResult <- 2msg <- gettext("step halving factor reduced below minimum in NLS step")if (controlvals$returnObject) {warning(msg)break} else stop(msg)}oldPars <- c(spar, oldPars)spar[] <- work$thetaNLSif (length(coef(gnlsSt)) == 0 && work$settings[5] < controlvals$nlsMaxIter) {break}attr(gnlsSt, "conLin")$Xy[] <- work$additionalattr(gnlsSt, "conLin")$logLik <- 0if (verbose) {cat("\nNLS step: RSS = ", format(work$settings[6]), "\n model parameters:")for (i in 1:pLen) cat(format(signif(spar[i]))," ")cat("\n iterations:",work$settings[5],"\n")}aConv <- c(spar, aConv)conv <- abs((oldPars - aConv)/ifelse(abs(aConv) < controlvals$tolerance, 1, aConv))aConv <- c(max(conv[1:pLen]))names(aConv) <- "params"if (length(conv) > pLen) {conv <- conv[-(1:pLen)]for(i in names(gnlsSt)) {if (any(parMap[,i])) {aConv <- c(aConv, max(conv[parMap[,i]]))names(aConv)[length(aConv)] <- i}}}if (verbose) {cat("\nConvergence:\n")print(aConv)}if ((max(aConv) <= controlvals$tolerance) ||(aConv["params"] <= controlvals$tolerance && convIter == 1)) {## convResult <- 0break}if (numIter >= controlvals$maxIter) {## convResult <- 1msg <- "maximum number of iterations reached without convergence"if (controlvals$returnObject) {warning(msg)break} else stop(msg)}} ## end{ repeat } --------------## wraping upww <- eval(modelExpression[[2]], envir = nlEnv)auxRes <- ww[NReal * pLen + (1:NReal)]attr(gnlsSt, "conLin")$Xy <- array(ww, c(NReal, pLen + 1))attr(gnlsSt, "conLin") <- c.L <- recalc(gnlsSt)## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsif((sigma <- controlvals$sigma) == 0) {sigma <- sqrt(sum((c.L$Xy[, pLen + 1])^2)/(NReal - pLen))lsig <- log(sigma) + 0.5 * log(1 - pLen/NReal)loglik <- ( - NReal * (1 + log(2 * pi) + 2 * lsig))/2 + c.L$logLik} else {lsig <- log(sigma)loglik <- - (NReal * (log(2 * pi)/2 + lsig) +sum((c.L$Xy[, pLen + 1])^2) / (2 * sigma^2)) + c.L$logLik}## ####varBeta <- qr(c.L$Xy[ , 1:pLen, drop = FALSE])if (varBeta$rank < pLen) {## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsprint("approximate covariance matrix for parameter estimates not of full rank")return()}attr(parAssign, "varBetaFact") <- varBeta <-sigma * t(backsolve(qr.R(varBeta), diag(pLen)))varBeta <- crossprod(varBeta)dimnames(varBeta) <- list(pn, pn)#### fitted.values and residuals (in original order)##Resid <- resid(gnlsSt)Fitted <- yShrunk - Residattr(Resid, "std") <- sigma/(varWeights(gnlsSt))if (!is.null(groups)) {attr(Resid, "std") <- attr(Resid, "std")[revOrderShrunk]Resid[] <- Resid[revOrderShrunk]Fitted[] <- Fitted[revOrderShrunk]grpShrunk[] <- grpShrunk[revOrderShrunk]}names(Resid) <- names(Fitted) <- origOrderShrunk## getting the approximate var-cov of the parameters## first making Xy into single column array againattr(gnlsSt, "conLin")$Xy <- array(auxRes, c(NReal, 1))## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsattr(gnlsSt, "fixedSigma") <- (controlvals$sigma > 0)apVar <-if (controlvals$apVar)gnlsApVar(gnlsSt, lsig, .relStep = controlvals[[".relStep"]],minAbsPar = controlvals[["minAbsParApVar"]])else "Approximate variance-covariance matrix not available"## getting rid of condensed linear model and fitoClass <- class(gnlsSt)attributes(gnlsSt) <-attributes(gnlsSt)[!is.na(match(names(attributes(gnlsSt)),## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsc("names","pmap","fixedSigma")))]class(gnlsSt) <- oClassgrpDta <- inherits(data, "groupedData")#### creating the gnls object##structure(class = c("gnls", "gls"),list(modelStruct = gnlsSt,dims = Dims,contrasts = contr,coefficients = spar,varBeta = varBeta,## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionssigma = if(controlvals$sigma) controlvals$sigma else sigma,apVar = apVar,logLik = loglik,numIter = numIter,groups = grpShrunk,call = Call,method = "ML",fitted = Fitted,residuals = Resid,plist = plist,pmap = pmap,parAssign = parAssign,formula = form,na.action = attr(dataMod, "na.action")),## saving labels and units for plotsunits = if(grpDta) attr(data, "units"),labels= if(grpDta) attr(data, "labels"))} ## end{gnls}### Auxiliary functions used internally in gls and its methodsgnlsApVar <-function(gnlsSt, lsigma, conLin = attr(gnlsSt, "conLin"),.relStep = (.Machine$double.eps)^(1/3), minAbsPar = 0,natural = TRUE){## calculate approximate variance-covariance matrix of all parameters## except the coefficientsfullGnlsLogLik <-function(Pars, object, conLin, N) {## logLik as a function of sigma and coef(glsSt)## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative SolutionsfixedSigma <- attr(object,"fixedSigma")npar <- length(Pars)if (!fixedSigma) {lsigma <- Pars[npar]Pars <- Pars[-npar]} else {lsigma <- log(conLin$sigma)}#######coef(object) <- ParsconLin <- recalc(object, conLin)conLin[["logLik"]] - N * lsigma - sum(conLin$Xy^2)/(2*exp(2*lsigma))}fixedSigma <- attr(gnlsSt,"fixedSigma")if (length(gnlsCoef <- coef(gnlsSt)) > 0) {cSt <- gnlsSt[["corStruct"]]if (!is.null(cSt) && inherits(cSt, "corSymm") && natural) {cStNatPar <- coef(cSt, unconstrained = FALSE)class(cSt) <- c("corNatural", "corStruct")coef(cSt) <- log((cStNatPar + 1)/(1 - cStNatPar))gnlsSt[["corStruct"]] <- cStgnlsCoef <- coef(gnlsSt)}dims <- conLin$dimsN <- dims$NconLin[["logLik"]] <- 0 # making sure## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative SolutionsPars <- if(fixedSigma) gnlsCoef else c(gnlsCoef, lSigma = lsigma)# log(sigma) is used as input in contrast to glsval <- fdHess(Pars, fullGnlsLogLik, gnlsSt, conLin, N,.relStep = .relStep, minAbsPar = minAbsPar)[["Hessian"]]if (all(eigen(val, only.values=TRUE)$values < 0)) {## negative definite - OKval <- solve(-val)## ## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutions## if(fixedSigma && !is.null(dim(val))){## Pars <- c(gnlsCoef, lSigma = lsigma)## npars<-length(Pars)## val<-cbind(val,rep(0,npars-1))## val<-rbind(val,rep(0,npars))## }nP <- names(Pars)dimnames(val) <- list(nP, nP)attr(val, "Pars") <- Parsattr(val, "natural") <- naturalval} else {## problem - solution is not maximum"Non-positive definite approximate variance-covariance"}} else {NULL}}###### function used to calculate the parameters from### the params and random effects###getParsGnls <- function(plist, pmap, beta, N){pars <- array(0, c(N, length(plist)), list(NULL, names(plist)))for (nm in names(plist)) {pars[, nm] <-if (is.logical(p <- plist[[nm]]))beta[pmap[[nm]]]elsep %*% beta[pmap[[nm]]]}pars}###### Methods for standard generics###coef.gnls <- function(object, ...) object$coefficientsformula.gnls <- function(x, ...) x$formula %||% eval(x$call[["model"]])getData.gnls <-function(object){mCall <- object$calldata <- eval(mCall$data)if (is.null(data)) return(data)naPat <- eval(mCall$naPattern)if (!is.null(naPat)) {data <- data[eval(naPat[[2]], data), , drop = FALSE]}naAct <- eval(mCall$na.action)if (!is.null(naAct)) {data <- naAct(data)}subset <- mCall$subsetif (!is.null(subset)) {subset <- eval(asOneSidedFormula(subset)[[2]], data)data <- data[subset, ]}data}logLik.gnls <-## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsfunction(object, REML = FALSE, ...){if (REML) {stop("cannot calculate REML log-likelihood for \"gnls\" objects")}## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative SolutionsfixSig <- attr(object[["modelStruct"]], "fixedSigma")fixSig <- !is.null(fixSig) && fixSigp <- object$dims$pN <- object$dims$Nval <- object[["logLik"]]attr(val, "nobs") <- attr(val, "nall") <- N## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsattr(val, "df") <- p + length(coef(object[["modelStruct"]])) + as.integer(!fixSig)class(val) <- "logLik"val}nobs.gnls <- function(object, ...) object$dims$Npredict.gnls <-function(object, newdata, na.action = na.fail, naPattern = NULL, ...){#### method for predict() designed for objects inheriting from class gnls##if (missing(newdata)) { # will return fitted valuesreturn(fitted(object))}newdata <- data.frame(newdata, check.names = FALSE)mCall <- object$call## use xlev to make sure factor levels are the same as in contrasts## and to support character-type 'newdata' for factorscontr <- object$contrastsdataMod <- model.frame(formula =asOneFormula(formula(object),mCall$params, naPattern,omit = c(names(object$plist), "pi",deparse(getResponseFormula(object)[[2]]))),data = newdata, na.action = na.action,drop.unused.levels = TRUE,xlev = lapply(contr, rownames))N <- nrow(dataMod)#### evaluating the naPattern expression, if any##naPat <- if (is.null(naPattern)) rep(TRUE, N)else as.logical(eval(asOneSidedFormula(naPattern)[[2]], dataMod))#### Getting the plist for the new data frame##plist <- object$plistpnames <- names(plist)if (is.null(params <- eval(object$call$params))) {params <- list(formula(paste0(paste(pnames, collapse = "+"), "~ 1")))}else if (!is.list(params)) params <- list(params)params <- unlist(lapply(params, function(pp) {if (is.name(pp[[2]])) {list(pp)} else {## multiple parameters on left hand sideeval(parse(text = paste("list(",paste(paste(all.vars(pp[[2]]), deparse(pp[[3]]), sep = "~"),collapse = ","),")")))}}), recursive=FALSE)names(params) <- pnamesprs <- coef(object)## pn <- names(prs)for(nm in pnames) {if (!is.logical(plist[[nm]])) {form1s <- asOneSidedFormula(params[[nm]][[3]])plist[[nm]] <- model.matrix(form1s, model.frame(form1s, dataMod), contr)}}modForm <- getCovariateFormula(object)[[2]]val <- eval(modForm, data.frame(dataMod,getParsGnls(plist, object$pmap, prs, N)))[naPat]names(val) <- row.names(newdata)lab <- "Predicted values"if (!is.null(aux <- attr(object, "units")$y)) {lab <- paste(lab, aux)}attr(val, "label") <- labval}#based on R's update.defaultupdate.gnls <-function (object, model., ..., evaluate = TRUE){call <- object$callif (is.null(call))stop("need an object with call component")extras <- match.call(expand.dots = FALSE)$...if (!missing(model.))call$model <- update.formula(formula(object), model.)if(length(extras) > 0) {existing <- !is.na(match(names(extras), names(call)))## do these individually to allow NULL to remove entries.for (a in names(extras)[existing]) call[[a]] <- extras[[a]]if(any(!existing))call <- as.call(c(as.list(call), extras[!existing]))}if(evaluate) eval(call, parent.frame())else call}#update.gnls <-# function(object, model, data = sys.frame(sys.parent()), params, start ,# correlation = NULL, weights = NULL, subset,# na.action = na.fail, naPattern, control = list(),# verbose = FALSE, ...)#{# thisCall <- as.list(match.call())[-(1:2)]# nextCall <- as.list(object$call)[-1]# if (!is.null(thisCall$model)) {# thisCall$model <- update(formula(object), model)# } else { # same model# if (is.null(thisCall$start)) {# thisCall$start <- coef(object)# }# }# if (is.na(match("correlation", names(thisCall))) &&# !is.null(thCor <- object$modelStruct$corStruct)) {# thisCall$correlation <- thCor# }# if (is.na(match("weights", names(thisCall))) &&# !is.null(thWgt <- object$modelStruct$varStruct)) {# thisCall$weights <- thWgt# }# nextCall[names(thisCall)] <- thisCall# do.call("gnls", nextCall)#}###*### gnlsStruct - a model structure for gnls fitsgnlsStruct <-## constructor for gnlsStruct objectsfunction(corStruct = NULL, varStruct = NULL){val <- list(corStruct = corStruct, varStruct = varStruct)val <- val[!sapply(val, is.null)] # removing NULL components# attr(val, "settings") <- attr(val$reStruct, "settings")# attr(val, "resp") <- resp# attr(val, "model") <- model# attr(val, "local") <- local# attr(val, "N") <- N# attr(val, "naPat") <- naPatclass(val) <- c("gnlsStruct", "glsStruct", "modelStruct")val}##*## gnlsStruct methods for standard genericsfitted.gnlsStruct <- function(object, ...) attr(object, "resp") - resid(object)Initialize.gnlsStruct <- function(object, data, ...){if (length(object)) {object[] <- lapply(object, Initialize, data)theta <- lapply(object, coef)len <- lengths(theta)num <- seq_along(len)pmap <-if (sum(len) > 0)outer(rep(num, len), num, "==")elsearray(FALSE, c(1, length(len)))dimnames(pmap) <- list(NULL, names(object))attr(object, "pmap") <- pmapif (needUpdate(object))object <- update(object, data)}object}logLik.gnlsStruct <-function(object, Pars, conLin = attr(object, "conLin"), ...){coef(object) <- Pars# updating parameter valuesconLin <- recalc(object, conLin)## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsif(conLin$sigma == 0) {conLin[["logLik"]] - (conLin$dims$N * log(sum(conLin$Xy^2)))/2} else {conLin[["logLik"]] - conLin$dims$N * log(conLin$sigma) -sum(conLin$Xy^2) / (2 * conLin$sigma^2)}}residuals.gnlsStruct <- function(object, ...) {c(eval(attr(object, "model")[[2]], envir = attr(object, "local")))}gnlsControl <-## Set control values for iterations within gnlsfunction(maxIter = 50, nlsMaxIter = 7, msMaxIter = 50,minScale = 0.001, tolerance = 1e-6, nlsTol = 0.001,msTol = 1e-7,returnObject = FALSE, msVerbose = FALSE,apVar = TRUE, .relStep = .Machine$double.eps^(1/3),opt = c("nlminb", "optim"), optimMethod = "BFGS",## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative SolutionsminAbsParApVar = 0.05, sigma=NULL){## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutionsif(is.null(sigma))sigma <- 0else if(!is.finite(sigma) || length(sigma) != 1 || sigma < 0)stop("Within-group std. dev. must be a positive numeric value")list(maxIter = maxIter, nlsMaxIter = nlsMaxIter, msMaxIter = msMaxIter,minScale = minScale, tolerance = tolerance, nlsTol = nlsTol,msTol = msTol, returnObject = returnObject,msVerbose = msVerbose, apVar = apVar,opt = match.arg(opt), optimMethod = optimMethod,## 17-11-2015; Fixed sigma patch; SH Heisterkamp; Quantitative Solutions.relStep = .relStep, minAbsParApVar = minAbsParApVar, sigma=sigma)}## Local Variables:## ess-indent-offset: 2## End: