Reputation: 4599
I have a rather specific regular expressions problem that is causing me some grief. I have removed one or more fixed effects from a mixed model (either lme
or lme4
), and wish to remove the corresponding random slope(s). However, depending on the random structure, this may leave behind unnecessary +
symbols or, worse, leave nothing preceding the |
.
Take a list of random effects formulae from lme
and lme4
obtained using lme.model$call$random
and findbars(formula(lme4.model))
respectively:
random.structures = list(
"~ b | random1",
"(b | random1)",
"~ b + x1 | random1",
"(b + x1 | random1)",
"~ x1 + b| random1",
"(x1 + b| random1)",
"~ b + x1 + c | random1",
"(b+ x1 + c | random1)",
"~b + x1 + x2 | random1",
"(b + x1 + x2 | random1)",
"~ x1 + x2 + b | random1",
"(x1 + x2 + b | random1)"
)
I have removed the variables b
and c
from the fixed effects formula using dropterms
. Since they no longer exist as fixed effects, their random slopes should not be allowed to vary.
b
and c
can be removed from the random formulae above using the following line:
random.structures = lapply(random.structures, function(i) gsub("b|c", "", i))
Now, I wish to remove all leftover +
symbols, i.e., those that do not link variables.
Then, in the event there is a blank space between ~
or (
and |
, I wish to insert a 1
.
The desired output is
random.structures2 = list(
"~ 1 | random1",
"(1 | random1)",
"~ x1 | random1",
"(x1 | random1)",
"~ x1 | random1",
"(x1 | random1)",
"~ x1 | random1",
"(x1 | random1)",
"~ x1 + x2 | random1",
"(x1 + x2 | random1)",
"~ x1 + x2 | random1",
"(x1 + x2 | random1)"
)
I have fiddled with gsub
but just can't seem to get it right. For instance, this works:
gsub("(.*)\\+\\ |(.*)\\+(\\|)", "\\1", random.structures[[3]])
# Accounting for space or lack of space between + and |
But not for this:
gsub("(.*)\\+\\ |(.*)\\+(\\|)", "\\1", random.structures[[7]])
Alternately, if there is a preexisting function like dropterms
for random structures, I'm all in!
Similarly, I can't reliable insert a 1
in the blank space inbetween ~ |
or ( |
.
Upvotes: 1
Views: 1192
Reputation: 206243
Half the items in your starting list are proper formulas (the ones with the "~"). I'm not sure what you are doing with the terms in the parenthesis. But for the formulas, you can use the Formula
package for better support for dropping terms with conditioning terms.
Here I'll subset to the proper formulas and convert to Formula
objects.
library(Formula)
rx <- lapply(random.structures[grep("~", random.structures)],
function(x) Formula(as.formula(x)))
We can quickly peak at the results with
sapply(rx, deparse)
# [1] "~b | random1"
# [2] "~b + x1 | random1"
# [3] "~x1 + b | random1"
# [4] "~b + x1 + c | random1"
# [5] "~b + x1 + x2 | random1"
# [6] "~x1 + x2 + b | random1"
Now we can remove b
and c
from all of these with
nx <- lapply(x, function(x) update(x, ~.-b-c))
and view the results with
sapply(nx, deparse)
# [1] "~1 | random1"
# [2] "~x1 | random1"
# [3] "~x1 | random1"
# [4] "~x1 | random1"
# [5] "~x1 + x2 | random1"
# [6] "~x1 + x2 | random1"
You should have no problem using these where ever you would use regular formulas.
Upvotes: 3