简体   繁体   中英

Extract components from mixed model (lme4) formula

I'm trying to write a function in R that accepts a formula such as the following:

y ~ 1 + sex + age + (1 | school) + (1 | school:section)

Is there an easy way to extract the various components of this formula for use in my function? For example, I would like to be able to get the left hand side, each of the variables, the random effects variables and how they are nested, etc.

Is there an easier way to do this than walking the formula parse tree?

If you want a solution which doesn't require regex, I suggest you consider terms .

form <- y ~ 1 + sex + age + (1 | school) + (1 | school:section)
terms(form)

## y ~ 1 + sex + age + (1 | school) + (1 | school:section)
## attr(,"variables")
## list(y, sex, age, 1 | school, 1 | school:section)
## attr(,"factors")
##                    sex age 1 | school 1 | school:section
## y                    0   0          0                  0
## sex                  1   0          0                  0
## age                  0   1          0                  0
## 1 | school           0   0          1                  0
## 1 | school:section   0   0          0                  1
## attr(,"term.labels")
## [1] "sex"                "age"                "1 | school"         "1 | school:section"
## attr(,"order")
## [1] 1 1 1 1
## attr(,"intercept")
## [1] 1
## attr(,"response")
## [1] 1
## attr(,".Environment")
## <environment: R_GlobalEnv>

Furthermore you can extract attributes from it using attributes :

attributes(terms(form))$term.labels

## [1] "sex"                "age"                "1 | school"         "1 | school:section"

To expand on @Ben Bolker's suggestion:

f1 <- formula(y ~ 1 + sex + age + (1 | school) + (1 | school:section))

The left hand side (assuming one variable on left):

all.vars(terms(f1))[1] # character

The variables:

all.vars(delete.response(terms(f1))) # character

The random effects:

lme4:::findbars(f1) # returns list of language items

There's also the formula.tools package for this, although it doesn't have methods specifically for mixed-effects models:

library(formula.tools)
lhs(f1)
r1 <- rhs.vars(f1) # gives fixed and random effects as character
r1[grepl("\\|", r1)] # character vector of random effects

Maybe something like:

x <- as.formula("y ~ 1 + sex + age + (1 | school) + (1 | school:section)")
x[[2]]
x[[3]][2]

You could use strsplit too as in:

strsplit(as.character(x[[3]][2]), "\\+")
> form <- y ~ 1 + sex + age + (1 | school) + (1 | school:section)
> form[1]
`~`()
> form[2]
y()
> form[3]
1 + sex + age + (1 | school) + (1 | school:section)()

So basically you should be addressing the LHS and the RHS as list elements. To split up the RHS you could use TylerRinker's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM