仅在第一次出现另一个模式之前查找模式(或:如何从混合效应模型的公式中删除随机效应)
Find pattern only until first occurrence of another pattern (or: how to remove random effects from a formula of mixed effects models)
我想从模型公式中提取信息,特别是我想删除随机效应以仅从混合模型(lme4-notation)中获得 "fixed effects part"。
为此,我在找到括号 (
之前搜索公式中的最后一个 +
。 +
之前的所有内容都必须是公式的 "fixed" 部分。这适用于具有固定效应预测变量/变量的模型。
但是,对于空模型(固定效应中的截距),可能没有 +
,例如如果公式是 Reaction ~ (Days | Subject)
。在这种情况下,我检查是否有 no +
-sign。但这不适用于具有 多个 随机部分的模型。在下面的示例中,grepl()
for f2
应该 return FALSE
,但是 returns TRUE
,因为 +
是在随机部分找到 second 开头的括号。
我的问题:如何在第一个 (
之后停止检查 +
,以便忽略可能的第二个或第三个随机效应项?以下示例的目标是 grepl()
-命令 return FALSE
、FALSE
、TRUE
、TRUE
.
f1 <- "Reaction ~ (1 + Days | Subject)"
f2 <- "Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)"
f3 <- "Reaction ~ x1 + x2 + (1 + Days | Subject)"
f4 <- "Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)"
# works!
grepl("\+(\s)*\((.*)\)", f1) # should return FALSE
#> [1] FALSE
# fails...
grepl("\+(\s)*\((.*)\)", f2) # should return FALSE
#> [1] TRUE
# works!
grepl("\+(\s)*\((.*)\)", f3) # should return TRUE
#> [1] TRUE
# works!
grepl("\+(\s)*\((.*)\)", f4) # should return TRUE
#> [1] TRUE
这并不是真正从 RE 角度回答您的问题(可能有答案),但如果您的目标是提取随机效应 and/or 固定效应公式,您可能会从中获得更多收益glFormula
和 lFormula
的源代码构成了 lme4
包本身。由于他们分别为固定效应和随机效应创建设计矩阵 X
和 Z
,因此他们必须在某些点提取各自的部分。
例如,要提取固定效应,使用函数 nobars
和 RHSForm
:
library(lme4)
f1 <- Reaction ~ (1 + Days | Subject)
f2 <- Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)
f3 <- Reaction ~ x1 + x2 + (1 + Days | Subject)
f4 <- Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
(f1FixedEffects <- nobars(lme4:::RHSForm(f1)) #note the triple 'lme4:::'. RHSForm is not exported to the public environment.
[1] 1
(f2FixedEffects <- nobars(lme4:::RHSForm(f2))
[1] 1
(f1FixedEffects <- nobars(lme4:::RHSForm(f3))
x1 + x2
(f1FixedEffects <- nobars(lme4:::RHSForm(f4))
x1 + x2
如果想要提取整个公式,您可以使用
lme4:::RHSForm(f1) <- nobars(lme4:::RHSForm(f1)
f1
Reaction ~ 1
或类似(感谢 AkselA 的评论)
nobars(f1)
Reaction ~ 1
对于固定效应。
请注意,我已将您的字符串公式转换为公式。这也可以用 'as.formula()'
来完成
Oliver 的回答是正确的,尤其是当您已经在使用 lme4
时,但还有一个 base
框架可以用来修改公式。
# Is read as class formula
f4 <- Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
# Isolate the terms and find which contains a vertical bar
f4t <- terms(f4)
dr <- grep("|", labels(f4t), fixed=TRUE)
# Drop the term(s) containing a vertical bar
f4td <- drop.terms(f4t, dr)
# Update the old formula with the new set of terms
f4u <- update(f4, f4td)
# Voilà
f4u
# Reaction ~ x1 + x2
如评论中所述,这在两种特殊情况下会失败:所有效果都是随机的,没有效果是随机的。为了妥善处理这些异常,我发现最好在编写函数时编写一个适当的函数。
drop_randfx <- function(form) {
form.t <- terms(form)
dr <- grepl("|", labels(form.t), fixed=TRUE)
if (mean(dr) == 1) {
form.u <- update(form, . ~ 1)
} else {
if (mean(dr) == 0) {
form.u <- form
} else {
form.td <- drop.terms(form.t, which(dr))
form.u <- update(form, form.td)
}
}
form.u
}
这通过了所有测试
f1 <- Reaction ~ (1 + Days | Subject)
f2 <- Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)
f3 <- Reaction ~ x1 + x2 + (1 + Days | Subject)
f4 <- Reaction ~ x1 * x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
f5 <- Reaction ~ x1 + x2
sapply(list(f1, f2, f3, f4, f5), drop_randfx) # [[1]]
# [[1]]
# Reaction ~ 1
#
# [[2]]
# Reaction ~ 1
#
# [[3]]
# Reaction ~ x1 + x2
#
# [[4]]
# Reaction ~ x1 + x2 + x1:x2
#
# [[5]]
# Reaction ~ x1 + x2
我想从模型公式中提取信息,特别是我想删除随机效应以仅从混合模型(lme4-notation)中获得 "fixed effects part"。
为此,我在找到括号 (
之前搜索公式中的最后一个 +
。 +
之前的所有内容都必须是公式的 "fixed" 部分。这适用于具有固定效应预测变量/变量的模型。
但是,对于空模型(固定效应中的截距),可能没有 +
,例如如果公式是 Reaction ~ (Days | Subject)
。在这种情况下,我检查是否有 no +
-sign。但这不适用于具有 多个 随机部分的模型。在下面的示例中,grepl()
for f2
应该 return FALSE
,但是 returns TRUE
,因为 +
是在随机部分找到 second 开头的括号。
我的问题:如何在第一个 (
之后停止检查 +
,以便忽略可能的第二个或第三个随机效应项?以下示例的目标是 grepl()
-命令 return FALSE
、FALSE
、TRUE
、TRUE
.
f1 <- "Reaction ~ (1 + Days | Subject)"
f2 <- "Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)"
f3 <- "Reaction ~ x1 + x2 + (1 + Days | Subject)"
f4 <- "Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)"
# works!
grepl("\+(\s)*\((.*)\)", f1) # should return FALSE
#> [1] FALSE
# fails...
grepl("\+(\s)*\((.*)\)", f2) # should return FALSE
#> [1] TRUE
# works!
grepl("\+(\s)*\((.*)\)", f3) # should return TRUE
#> [1] TRUE
# works!
grepl("\+(\s)*\((.*)\)", f4) # should return TRUE
#> [1] TRUE
这并不是真正从 RE 角度回答您的问题(可能有答案),但如果您的目标是提取随机效应 and/or 固定效应公式,您可能会从中获得更多收益glFormula
和 lFormula
的源代码构成了 lme4
包本身。由于他们分别为固定效应和随机效应创建设计矩阵 X
和 Z
,因此他们必须在某些点提取各自的部分。
例如,要提取固定效应,使用函数 nobars
和 RHSForm
:
library(lme4)
f1 <- Reaction ~ (1 + Days | Subject)
f2 <- Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)
f3 <- Reaction ~ x1 + x2 + (1 + Days | Subject)
f4 <- Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
(f1FixedEffects <- nobars(lme4:::RHSForm(f1)) #note the triple 'lme4:::'. RHSForm is not exported to the public environment.
[1] 1
(f2FixedEffects <- nobars(lme4:::RHSForm(f2))
[1] 1
(f1FixedEffects <- nobars(lme4:::RHSForm(f3))
x1 + x2
(f1FixedEffects <- nobars(lme4:::RHSForm(f4))
x1 + x2
如果想要提取整个公式,您可以使用
lme4:::RHSForm(f1) <- nobars(lme4:::RHSForm(f1)
f1
Reaction ~ 1
或类似(感谢 AkselA 的评论)
nobars(f1)
Reaction ~ 1
对于固定效应。
请注意,我已将您的字符串公式转换为公式。这也可以用 'as.formula()'
来完成Oliver 的回答是正确的,尤其是当您已经在使用 lme4
时,但还有一个 base
框架可以用来修改公式。
# Is read as class formula
f4 <- Reaction ~ x1 + x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
# Isolate the terms and find which contains a vertical bar
f4t <- terms(f4)
dr <- grep("|", labels(f4t), fixed=TRUE)
# Drop the term(s) containing a vertical bar
f4td <- drop.terms(f4t, dr)
# Update the old formula with the new set of terms
f4u <- update(f4, f4td)
# Voilà
f4u
# Reaction ~ x1 + x2
如评论中所述,这在两种特殊情况下会失败:所有效果都是随机的,没有效果是随机的。为了妥善处理这些异常,我发现最好在编写函数时编写一个适当的函数。
drop_randfx <- function(form) {
form.t <- terms(form)
dr <- grepl("|", labels(form.t), fixed=TRUE)
if (mean(dr) == 1) {
form.u <- update(form, . ~ 1)
} else {
if (mean(dr) == 0) {
form.u <- form
} else {
form.td <- drop.terms(form.t, which(dr))
form.u <- update(form, form.td)
}
}
form.u
}
这通过了所有测试
f1 <- Reaction ~ (1 + Days | Subject)
f2 <- Reaction ~ (1 | mygrp/mysubgrp) + (1 | Subject)
f3 <- Reaction ~ x1 + x2 + (1 + Days | Subject)
f4 <- Reaction ~ x1 * x2 + (1 | mygrp/mysubgrp) + (1 | Subject)
f5 <- Reaction ~ x1 + x2
sapply(list(f1, f2, f3, f4, f5), drop_randfx) # [[1]]
# [[1]]
# Reaction ~ 1
#
# [[2]]
# Reaction ~ 1
#
# [[3]]
# Reaction ~ x1 + x2
#
# [[4]]
# Reaction ~ x1 + x2 + x1:x2
#
# [[5]]
# Reaction ~ x1 + x2