Formula/0000755000176200001440000000000014376075316011673 5ustar liggesusersFormula/NAMESPACE0000644000176200001440000000143712360223605013102 0ustar liggesusersimport("stats") export( "Formula", "as.Formula", "is.Formula", "model.part" ## "has.intercept" ) ## methods for class "Formula" S3method("formula", "Formula") S3method("terms", "Formula") S3method("model.frame", "Formula") S3method("model.matrix", "Formula") S3method("update", "Formula") S3method("length", "Formula") S3method("print", "Formula") S3method("all.equal", "Formula") S3method("str", "Formula") ## methods to as.Formula() S3method("as.Formula", "default") S3method("as.Formula", "formula") S3method("as.Formula", "Formula") ## ## methods to has.intercept() ## S3method("has.intercept", "default") ## S3method("has.intercept", "formula") ## S3method("has.intercept", "Formula") ## methods to model.part() S3method("model.part", "formula") S3method("model.part", "Formula") Formula/man/0000755000176200001440000000000014375766347012460 5ustar liggesusersFormula/man/Formula.Rd0000644000176200001440000001231613742312071014331 0ustar liggesusers\name{Formula} \alias{Formula} \alias{formula.Formula} \alias{as.Formula} \alias{as.Formula.default} \alias{as.Formula.formula} \alias{as.Formula.Formula} \alias{is.Formula} \alias{print.Formula} \alias{update.Formula} \alias{length.Formula} \alias{all.equal.Formula} \alias{str.Formula} \title{Extended Formulas: Multiple Responses and Multiple Regressor Parts} \description{ The new class \code{Formula} extends the base class \code{\link[stats]{formula}} by allowing for multiple responses and multiple parts of regressors. } \usage{ Formula(object) \method{formula}{Formula}(x, lhs = NULL, rhs = NULL, collapse = FALSE, update = FALSE, drop = TRUE, \dots) as.Formula(x, \dots) is.Formula(object) } \arguments{ \item{object, x}{an object. For \code{Formula} it needs to be a \code{formula} object.} \item{lhs, rhs}{indexes specifying which elements of the left- and right-hand side, respectively, should be employed. \code{NULL} corresponds to all parts, \code{0} to none.} \item{collapse}{logical. Should multiple parts (if any) be collapsed to a single part (essentially by replacing the \code{|} operator by \code{+})? \code{collapse} can be a vector of length 2, corresponding for different handling of left- and right-hand side respectively.} \item{update}{logical. Only used if \code{all(collapse)}. Should the resulting formula be updated to remove possibly redundant terms occuring in multiple terms?} \item{drop}{logical. Should the \code{Formula} class be dropped? If \code{TRUE} (the default) a \code{formula} is returned, if \code{FALSE} the corresponding \code{Formula} is returned.} \item{\dots}{further arguments.} } \details{ \code{Formula} objects extend the basic \code{formula} objects. These extensions include multi-part formulas such as \code{y ~ x1 + x2 | u1 + u2 + u3 | v1 + v2}, multiple response formulas \code{y1 + y2 ~ x1 + x2 + x3}, multi-part responses such as \code{y1 | y2 + y3 ~ x}, and combinations of these. The \code{Formula} creates a \code{Formula} object from a \code{formula} which can have the \code{|} operator on the left- and/or right-hand side (LHS and/or RHS). Essentially, it stores the original \code{formula} along with attribute lists containing the decomposed parts for the LHS and RHS, respectively. The main motivation for providing the \code{Formula} class is to be able to conveniently compute model frames and model matrices or extract selected responses based on an extended formula language. This functionality is provided by methods to the generics \code{\link[stats]{model.frame}}, and \code{\link[stats]{model.matrix}}. For details and examples, see their manual page: \code{\link{model.frame.Formula}}. In addition to these workhorses, a few further methods and functions are provided. By default, the \code{formula()} method switches back to the original \code{formula}. Additionally, it allows selection of subsets of the LHS and/or RHS (via \code{lhs}, and \code{rhs}) and collapsing multiple parts on the LHS and/or RHS into a single part (via \code{collapse}). \code{is.Formula} checks whether the argument inherits from the \code{Formula} class. \code{as.Formula} is a generic for coercing to \code{Formula}, the default method first coerces to \code{formula} and then calls \code{Formula}. The default and \code{formula} method also take an optional \code{env} argument, specifying the environment of the resulting \code{Formula}. In the latter case, this defaults to the environment of the \code{formula} supplied. Methods to further standard generics \code{\link[base]{print}}, \code{\link[stats]{update}}, and \code{\link[base]{length}} are provided for \code{Formula} objects. The latter reports the number of parts on the LHS and RHS, respectively. } \value{ \code{Formula} returns an object of class \code{Formula} which inherits from \code{formula}. It is the original \code{formula} plus two attributes \code{"lhs"} and \code{"rhs"} that contain the parts of the decomposed left- and right-hand side, respectively. } \references{ Zeileis A, Croissant Y (2010). Extended Model Formulas in R: Multiple Parts and Multiple Responses. \emph{Journal of Statistical Software}, \bold{34}(1), 1--13. \doi{10.18637/jss.v034.i01} } \seealso{\code{\link{model.frame.Formula}}} \examples{ ## create a simple Formula with one response and two regressor parts f1 <- y ~ x1 + x2 | z1 + z2 + z3 F1 <- Formula(f1) class(F1) length(F1) ## switch back to original formula formula(F1) ## create formula with various transformations formula(F1, rhs = 1) formula(F1, collapse = TRUE) formula(F1, lhs = 0, rhs = 2) ## put it together from its parts as.Formula(y ~ x1 + x2, ~ z1 + z2 + z3) ## update the formula update(F1, . ~ . + I(x1^2) | . - z2 - z3) update(F1, . | y2 + y3 ~ .) # create a multi-response multi-part formula f2 <- y1 | y2 + y3 ~ x1 + I(x2^2) | 0 + log(x1) | x3 / x4 F2 <- Formula(f2) length(F2) ## obtain various subsets using standard indexing ## no lhs, first/seconde rhs formula(F2, lhs = 0, rhs = 1:2) formula(F2, lhs = 0, rhs = -3) formula(F2, lhs = 0, rhs = c(TRUE, TRUE, FALSE)) ## first lhs, third rhs formula(F2, lhs = c(TRUE, FALSE), rhs = 3) } \keyword{classes} Formula/man/model.frame.Formula.Rd0000644000176200001440000001724513742312063016530 0ustar liggesusers\name{model.frame.Formula} \alias{terms.Formula} \alias{model.matrix.Formula} \alias{model.frame.Formula} \alias{model.part} \alias{model.part.formula} \alias{model.part.Formula} \title{Model Frame/Matrix/Response Construction for Extended Formulas} \description{ Computation of model frames, model matrices, and model responses for extended formulas of class \code{Formula}. } \usage{ \method{model.frame}{Formula}(formula, data = NULL, \dots, lhs = NULL, rhs = NULL, dot = "separate") \method{model.matrix}{Formula}(object, data = environment(object), \dots, lhs = NULL, rhs = 1, dot = "separate") \method{terms}{Formula}(x, \dots, lhs = NULL, rhs = NULL, dot = "separate") model.part(object, \dots) \method{model.part}{Formula}(object, data, lhs = 0, rhs = 0, drop = FALSE, terms = FALSE, dot = NULL, \dots) } \arguments{ \item{formula, object, x}{an object of class \code{Formula}.} \item{data}{a data.frame, list or environment containing the variables in \code{formula}. For \code{model.part} it needs to be the \code{model.frame}.} \item{lhs, rhs}{indexes specifying which elements of the left- and right-hand side, respectively, should be employed. \code{NULL} corresponds to all parts, \code{0} to none. At least one \code{lhs} or one \code{rhs} has to be specified.} \item{dot}{character specifying how to process formula parts with a dot (\code{.}) on the right-hand side. This can be: \code{"separate"} so that each formula part is expanded separately. \code{"sequential"} so that the parts are expanded sequentially conditional on all prior parts. \code{"previous"} so the part is expanded to the previous part.} \item{drop}{logical. Should the \code{data.frame} be dropped for single column data frames?} \item{terms}{logical. Should the \code{"terms"} attribute (corresponding to the \code{model.part} extracted) be added?} \item{\dots}{further arguments passed to the respective \code{formula} methods.} } \details{ All three model computations leverage the corresponding standard methods. Additionally, they allow specification of the part(s) of the left- and right-hand side (LHS and RHS) that should be included in the computation. The idea underlying all three model computations is to extract a suitable \code{formula} from the more general \code{Formula} and then calling the standard \code{\link[stats]{model.frame}}, \code{\link[stats]{model.matrix}}, and \code{\link[stats]{terms}} methods. More specifically, if the \code{Formula} has multiple parts on the RHS, they are collapsed, essentially replacing \code{|} by \code{+}. If there is only a single response on the LHS, then it is kept on the LHS. Otherwise all parts of the formula are collapsed on the RHS (because \code{formula} objects can not have multiple responses). Hence, for multi-response \code{Formula} objects, the (non-generic) \code{\link[stats:model.extract]{model.response}} does not give the correct results. To avoid confusion a new generic \code{model.part} with suitable \code{formula} method is provided which can always be used instead of \code{model.response}. Note, however, that it has a different syntax: It requires the \code{Formula} object in addition to the readily processed \code{model.frame} supplied in data (and optionally the \code{lhs}). Also, it returns either a \code{data.frame} with multiple columns or a single column (dropping the \code{data.frame} property) depending on whether multiple responses are employed or not. If the the formula contains one or more dots (\code{.}), some care has to be taken to process these correctly, especially if the LHS contains transformartions (such as \code{log}, \code{sqrt}, \code{cbind}, \code{Surv}, etc.). Calling the \code{terms} method with the original data (untransformed, if any) resolves all dots (by default separately for each part, otherwise sequentially) and also includes the original and updated formula as part of the terms. When calling \code{model.part} either the original untransformed data should be provided along with a \code{dot} specification or the transformed \code{model.frame} from the same formula without another \code{dot} specification (in which case the \code{dot} is inferred from the \code{terms} of the \code{model.frame}). } \references{ Zeileis A, Croissant Y (2010). Extended Model Formulas in R: Multiple Parts and Multiple Responses. \emph{Journal of Statistical Software}, \bold{34}(1), 1--13. \doi{10.18637/jss.v034.i01} } \seealso{\code{\link{Formula}}, \code{\link[stats]{model.frame}}, \code{\link[stats]{model.matrix}}, \code{\link[stats]{terms}}, \code{\link[stats:model.extract]{model.response}}} \examples{ ## artificial example data set.seed(1090) dat <- as.data.frame(matrix(round(runif(21), digits = 2), ncol = 7)) colnames(dat) <- c("y1", "y2", "y3", "x1", "x2", "x3", "x4") for(i in c(2, 6:7)) dat[[i]] <- factor(dat[[i]] > 0.5, labels = c("a", "b")) dat$y2[1] <- NA dat ###################################### ## single response and two-part RHS ## ###################################### ## single response with two-part RHS F1 <- Formula(log(y1) ~ x1 + x2 | I(x1^2)) length(F1) ## set up model frame mf1 <- model.frame(F1, data = dat) mf1 ## extract single response model.part(F1, data = mf1, lhs = 1, drop = TRUE) model.response(mf1) ## model.response() works as usual ## extract model matrices model.matrix(F1, data = mf1, rhs = 1) model.matrix(F1, data = mf1, rhs = 2) ######################################### ## multiple responses and multiple RHS ## ######################################### ## set up Formula F2 <- Formula(y1 + y2 | log(y3) ~ x1 + I(x2^2) | 0 + log(x1) | x3 / x4) length(F2) ## set up full model frame mf2 <- model.frame(F2, data = dat) mf2 ## extract responses model.part(F2, data = mf2, lhs = 1) model.part(F2, data = mf2, lhs = 2) ## model.response(mf2) does not give correct results! ## extract model matrices model.matrix(F2, data = mf2, rhs = 1) model.matrix(F2, data = mf2, rhs = 2) model.matrix(F2, data = mf2, rhs = 3) ####################### ## Formulas with '.' ## ####################### ## set up Formula with a single '.' F3 <- Formula(y1 | y2 ~ .) mf3 <- model.frame(F3, data = dat) ## without y1 or y2 model.matrix(F3, data = mf3) ## without y1 but with y2 model.matrix(F3, data = mf3, lhs = 1) ## without y2 but with y1 model.matrix(F3, data = mf3, lhs = 2) ## set up Formula with multiple '.' F3 <- Formula(y1 | y2 | log(y3) ~ . - x3 - x4 | .) ## process both '.' separately (default) mf3 <- model.frame(F3, data = dat, dot = "separate") ## only x1-x2 model.part(F3, data = mf3, rhs = 1) ## all x1-x4 model.part(F3, data = mf3, rhs = 2) ## process the '.' sequentially, i.e., the second RHS conditional on the first mf3 <- model.frame(F3, data = dat, dot = "sequential") ## only x1-x2 model.part(F3, data = mf3, rhs = 1) ## only x3-x4 model.part(F3, data = mf3, rhs = 2) ## process the second '.' using the previous RHS element mf3 <- model.frame(F3, data = dat, dot = "previous") ## only x1-x2 model.part(F3, data = mf3, rhs = 1) ## x1-x2 again model.part(F3, data = mf3, rhs = 2) ############################## ## Process multiple offsets ## ############################## ## set up Formula F4 <- Formula(y1 ~ x3 + offset(x1) | x4 + offset(log(x2))) mf4 <- model.frame(F4, data = dat) ## model.part can be applied as above and includes offset! model.part(F4, data = mf4, rhs = 1) ## additionally, the corresponding corresponding terms can be included model.part(F4, data = mf4, rhs = 1, terms = TRUE) ## hence model.offset() can be applied to extract offsets model.offset(model.part(F4, data = mf4, rhs = 1, terms = TRUE)) model.offset(model.part(F4, data = mf4, rhs = 2, terms = TRUE)) } \keyword{models} Formula/DESCRIPTION0000644000176200001440000000160214376075316013400 0ustar liggesusersPackage: Formula Version: 1.2-5 Date: 2023-02-23 Title: Extended Model Formulas Description: Infrastructure for extended formulas with multiple parts on the right-hand side and/or multiple responses on the left-hand side (see ). Authors@R: c(person(given = "Achim", family = "Zeileis", role = c("aut", "cre"), email = "Achim.Zeileis@R-project.org", comment = c(ORCID = "0000-0003-0918-3766")), person(given = "Yves", family = "Croissant", role = "aut", email = "Yves.Croissant@univ-reunion.fr")) Depends: R (>= 2.0.0), stats License: GPL-2 | GPL-3 NeedsCompilation: no Packaged: 2023-02-23 22:47:03 UTC; zeileis Author: Achim Zeileis [aut, cre] (), Yves Croissant [aut] Maintainer: Achim Zeileis Repository: CRAN Date/Publication: 2023-02-24 08:52:30 UTC Formula/build/0000755000176200001440000000000014375766347013004 5ustar liggesusersFormula/build/vignette.rds0000644000176200001440000000042314375766347015342 0ustar liggesusersuQN -vjb_}1K_ɸ5$tλnEh9s/ BHNhb#PR6)^5OJ/Z`k#@Lj pkgname <- "Formula" > source(file.path(R.home("share"), "R", "examples-header.R")) > options(warn = 1) > library('Formula') > > base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') > cleanEx() > nameEx("Formula") > ### * Formula > > flush(stderr()); flush(stdout()) > > ### Name: Formula > ### Title: Extended Formulas: Multiple Responses and Multiple Regressor > ### Parts > ### Aliases: Formula formula.Formula as.Formula as.Formula.default > ### as.Formula.formula as.Formula.Formula is.Formula print.Formula > ### update.Formula length.Formula all.equal.Formula str.Formula > ### Keywords: classes > > ### ** Examples > > ## create a simple Formula with one response and two regressor parts > f1 <- y ~ x1 + x2 | z1 + z2 + z3 > F1 <- Formula(f1) > class(F1) [1] "Formula" "formula" > length(F1) [1] 1 2 > > ## switch back to original formula > formula(F1) y ~ x1 + x2 | z1 + z2 + z3 > > ## create formula with various transformations > formula(F1, rhs = 1) y ~ x1 + x2 > formula(F1, collapse = TRUE) y ~ x1 + x2 + (z1 + z2 + z3) > formula(F1, lhs = 0, rhs = 2) ~z1 + z2 + z3 > > ## put it together from its parts > as.Formula(y ~ x1 + x2, ~ z1 + z2 + z3) y ~ x1 + x2 | z1 + z2 + z3 > > ## update the formula > update(F1, . ~ . + I(x1^2) | . - z2 - z3) y ~ x1 + x2 + I(x1^2) | z1 > update(F1, . | y2 + y3 ~ .) y | y2 + y3 ~ x1 + x2 | z1 + z2 + z3 > > # create a multi-response multi-part formula > f2 <- y1 | y2 + y3 ~ x1 + I(x2^2) | 0 + log(x1) | x3 / x4 > F2 <- Formula(f2) > length(F2) [1] 2 3 > > ## obtain various subsets using standard indexing > ## no lhs, first/seconde rhs > formula(F2, lhs = 0, rhs = 1:2) ~x1 + I(x2^2) | 0 + log(x1) > formula(F2, lhs = 0, rhs = -3) ~x1 + I(x2^2) | 0 + log(x1) > formula(F2, lhs = 0, rhs = c(TRUE, TRUE, FALSE)) ~x1 + I(x2^2) | 0 + log(x1) > ## first lhs, third rhs > formula(F2, lhs = c(TRUE, FALSE), rhs = 3) y1 ~ x3/x4 > > > > cleanEx() > nameEx("model.frame.Formula") > ### * model.frame.Formula > > flush(stderr()); flush(stdout()) > > ### Name: model.frame.Formula > ### Title: Model Frame/Matrix/Response Construction for Extended Formulas > ### Aliases: terms.Formula model.matrix.Formula model.frame.Formula > ### model.part model.part.formula model.part.Formula > ### Keywords: models > > ### ** Examples > > ## artificial example data > set.seed(1090) > dat <- as.data.frame(matrix(round(runif(21), digits = 2), ncol = 7)) > colnames(dat) <- c("y1", "y2", "y3", "x1", "x2", "x3", "x4") > for(i in c(2, 6:7)) dat[[i]] <- factor(dat[[i]] > 0.5, labels = c("a", "b")) > dat$y2[1] <- NA > dat y1 y2 y3 x1 x2 x3 x4 1 0.82 0.27 0.09 0.22 b a 2 0.70 b 0.17 0.26 0.46 a a 3 0.65 a 0.28 0.03 0.37 b b > > ###################################### > ## single response and two-part RHS ## > ###################################### > > ## single response with two-part RHS > F1 <- Formula(log(y1) ~ x1 + x2 | I(x1^2)) > length(F1) [1] 1 2 > > ## set up model frame > mf1 <- model.frame(F1, data = dat) > mf1 log(y1) x1 x2 I(x1^2) 1 -0.1984509 0.09 0.22 0.0081 2 -0.3566749 0.26 0.46 0.0676 3 -0.4307829 0.03 0.37 9e-04 > > ## extract single response > model.part(F1, data = mf1, lhs = 1, drop = TRUE) 1 2 3 -0.1984509 -0.3566749 -0.4307829 > model.response(mf1) 1 2 3 -0.1984509 -0.3566749 -0.4307829 > ## model.response() works as usual > > ## extract model matrices > model.matrix(F1, data = mf1, rhs = 1) (Intercept) x1 x2 1 1 0.09 0.22 2 1 0.26 0.46 3 1 0.03 0.37 attr(,"assign") [1] 0 1 2 > model.matrix(F1, data = mf1, rhs = 2) (Intercept) I(x1^2) 1 1 0.0081 2 1 0.0676 3 1 0.0009 attr(,"assign") [1] 0 1 > > ######################################### > ## multiple responses and multiple RHS ## > ######################################### > > ## set up Formula > F2 <- Formula(y1 + y2 | log(y3) ~ x1 + I(x2^2) | 0 + log(x1) | x3 / x4) > length(F2) [1] 2 3 > > ## set up full model frame > mf2 <- model.frame(F2, data = dat) > mf2 y1 y2 log(y3) x1 I(x2^2) log(x1) x3 x4 2 0.70 b -1.771957 0.26 0.2116 -1.347074 a a 3 0.65 a -1.272966 0.03 0.1369 -3.506558 b b > > ## extract responses > model.part(F2, data = mf2, lhs = 1) y1 y2 2 0.70 b 3 0.65 a > model.part(F2, data = mf2, lhs = 2) log(y3) 2 -1.771957 3 -1.272966 > ## model.response(mf2) does not give correct results! > > ## extract model matrices > model.matrix(F2, data = mf2, rhs = 1) (Intercept) x1 I(x2^2) 2 1 0.26 0.2116 3 1 0.03 0.1369 attr(,"assign") [1] 0 1 2 > model.matrix(F2, data = mf2, rhs = 2) log(x1) 2 -1.347074 3 -3.506558 attr(,"assign") [1] 1 > model.matrix(F2, data = mf2, rhs = 3) (Intercept) x3b x3a:x4b x3b:x4b 2 1 0 0 0 3 1 1 0 1 attr(,"assign") [1] 0 1 2 2 attr(,"contrasts") attr(,"contrasts")$x3 [1] "contr.treatment" attr(,"contrasts")$x4 [1] "contr.treatment" > > ####################### > ## Formulas with '.' ## > ####################### > > ## set up Formula with a single '.' > F3 <- Formula(y1 | y2 ~ .) > mf3 <- model.frame(F3, data = dat) > ## without y1 or y2 > model.matrix(F3, data = mf3) (Intercept) y3 x1 x2 x3b x4b 2 1 0.17 0.26 0.46 0 0 3 1 0.28 0.03 0.37 1 1 attr(,"assign") [1] 0 1 2 3 4 5 attr(,"contrasts") attr(,"contrasts")$x3 [1] "contr.treatment" attr(,"contrasts")$x4 [1] "contr.treatment" > ## without y1 but with y2 > model.matrix(F3, data = mf3, lhs = 1) (Intercept) y2b y3 x1 x2 x3b x4b 2 1 1 0.17 0.26 0.46 0 0 3 1 0 0.28 0.03 0.37 1 1 attr(,"assign") [1] 0 1 2 3 4 5 6 attr(,"contrasts") attr(,"contrasts")$y2 [1] "contr.treatment" attr(,"contrasts")$x3 [1] "contr.treatment" attr(,"contrasts")$x4 [1] "contr.treatment" > ## without y2 but with y1 > model.matrix(F3, data = mf3, lhs = 2) (Intercept) y1 y3 x1 x2 x3b x4b 2 1 0.70 0.17 0.26 0.46 0 0 3 1 0.65 0.28 0.03 0.37 1 1 attr(,"assign") [1] 0 1 2 3 4 5 6 attr(,"contrasts") attr(,"contrasts")$x3 [1] "contr.treatment" attr(,"contrasts")$x4 [1] "contr.treatment" > > ## set up Formula with multiple '.' > F3 <- Formula(y1 | y2 | log(y3) ~ . - x3 - x4 | .) > ## process both '.' separately (default) > mf3 <- model.frame(F3, data = dat, dot = "separate") > ## only x1-x2 > model.part(F3, data = mf3, rhs = 1) x1 x2 2 0.26 0.46 3 0.03 0.37 > ## all x1-x4 > model.part(F3, data = mf3, rhs = 2) x1 x2 x3 x4 2 0.26 0.46 a a 3 0.03 0.37 b b > > ## process the '.' sequentially, i.e., the second RHS conditional on the first > mf3 <- model.frame(F3, data = dat, dot = "sequential") > ## only x1-x2 > model.part(F3, data = mf3, rhs = 1) x1 x2 2 0.26 0.46 3 0.03 0.37 > ## only x3-x4 > model.part(F3, data = mf3, rhs = 2) x3 x4 2 a a 3 b b > > ## process the second '.' using the previous RHS element > mf3 <- model.frame(F3, data = dat, dot = "previous") > ## only x1-x2 > model.part(F3, data = mf3, rhs = 1) x1 x2 2 0.26 0.46 3 0.03 0.37 > ## x1-x2 again > model.part(F3, data = mf3, rhs = 2) x1 x2 2 0.26 0.46 3 0.03 0.37 > > ############################## > ## Process multiple offsets ## > ############################## > > ## set up Formula > F4 <- Formula(y1 ~ x3 + offset(x1) | x4 + offset(log(x2))) > mf4 <- model.frame(F4, data = dat) > ## model.part can be applied as above and includes offset! > model.part(F4, data = mf4, rhs = 1) x3 offset(x1) 1 b 0.09 2 a 0.26 3 b 0.03 > ## additionally, the corresponding corresponding terms can be included > model.part(F4, data = mf4, rhs = 1, terms = TRUE) x3 offset(x1) 1 b 0.09 2 a 0.26 3 b 0.03 > ## hence model.offset() can be applied to extract offsets > model.offset(model.part(F4, data = mf4, rhs = 1, terms = TRUE)) [1] 0.09 0.26 0.03 > model.offset(model.part(F4, data = mf4, rhs = 2, terms = TRUE)) [1] -1.5141277 -0.7765288 -0.9942523 > > > > ### *