繁体   English   中英

如何从 lme4 中提取公式的随机效应部分

[英]How to extract just the random effects part of the formula from lme4

假设我安装了一个 model 这样的

mymodel <- lmer(Y~X1+(1|fac1)+(1|fac2),mydata)

如何仅提取公式 ( (1|fac1)+(1|fac2)的随机效应部分?

我知道我能做到

formula(mymodel)[-2]

但这只会返回X1 + (1| fac1) + (1| fac2)

我知道我可以用正则表达式做点什么,但我希望有更简单的方法。

查找栏

lme4 package 提供了findbars

library(lme4)

fo <- Y~X1+(1|fac1)+(1|fac2)

findbars(fo)
## [[1]]
## 1 | fac1
##
## [[2]]
## 1 | fac2

如果需要字符串,我们可以使用以下内容。 deparse1将处理deparse失败的某些不常见情况,但如果有必要在 R 早于 R 4.0.0 的版本中工作, deparse将主要作为替代方案工作。

sapply(findbars(fo), deparse1)
## [1] "1 | fac1" "1 | fac2"

如果所需的结果是公式的 RHS 但没有固定效应项,那么我们可以通过加回括号并使用reformulate来重构上述结果。 如果需要公式 object,请省略 [[2]]。 上面关于deparse1的讨论也适用于此。

reformulate(sprintf("(%s)", sapply(findbars(fo), deparse1)))[[2]]
## (1 | fac1) + (1 | fac2)

条款/标签

获取字符结果的另一种方法是使用将从terms中提取字符的labels 如果需要公式,请如上所述使用reformulate 这不使用任何包。

X <- grep("|", labels(terms(fo)), fixed = TRUE, value = TRUE)
X
## [1] "1 | fac1" "1 | fac2"

如上所述,公式及其右侧可以从X生成,如下所示:

reformulate(sprintf("(%s)", X))
reformulate(sprintf("(%s)", X))[[2]]

获取条款

另一种方法是使用getTerms from Terms of a sum in a R expression这个简短的 function 递归地遍历公式以提取术语。 它不使用任何包。

XX <- grep("|", sapply(getTerms(fo[[3]]), deparse1), fixed = TRUE, value = TRUE)
XX
## [1] "(1 | fac1)" "(1 | fac2)"

可以像这样生成公式和它的右侧:

reformulate(XX)
reformulate(XX)[[2]]

不需要正则表达式,但是,它仍然是字符串操作。

# stringsplit the output of your formula()
# remove the first entry 
# remove spaces with gsub()
# paste it back together

inp <- "X1 + (1| fac1) + (1| fac2)"

paste(gsub(" ", "", unlist(strsplit(inp, "+", fixed = T))[-1], fixed = T), 
      collapse = " + ")

# [1] "(1|fac1) + (1|fac2)"

一个可能无法概括的简单解决方案:

# This model may not make much sense, just for reproducibility
mymodel <- lmer(Petal.Length~Sepal.Width+(1|Species) + (1|Petal.Width),iris)    
stringr::str_extract_all(formula(mymodel),"\\(.*\\)")[3]
    [[1]]
    [1] "(1 | Species) + (1 | Petal.Width)"

要“自动”删除所有空元素:

purrr::compact(stringr::str_extract_all(formula(mymodel),"\\(.*\\)"))
[[1]]
[1] "(1 | Species) + (1 | Petal.Width)"

在看到 G Grthendieck 的回答后,我意识到我可能正在重新发明轮子,但这里有一种方法可以在不使用正则表达式的情况下从 model 中获取随机效果部分。 它使用递归来检查公式的 AST 中的每个调用,并仅将那些调用保留在括号中,然后将其重建为一个表达式。 我可能是错的,但这感觉比在字符串和语言对象之间切换更安全。 可以修改为仅拉出| 电话。

get_random_effects <- function(mod)
{
  rip_formula <- function(form) 
  {
    
    if(rlang::is_formula(form)) form <- as.list(form)[-c(1:2)][[1]]
    if(is.call(form)) {
      call_list <- as.list(form)
      if(as.character(call_list[[1]]) == "+") 
        return(unlist(lapply(call_list[-1], rip_formula)))
      if(as.character(call_list[[1]]) == "(") 
        return(form)
     } 
  }
  
  re_list <- rip_formula(formula(mod))
  while(length(re_list) > 2) 
    re_list <- c(as.call(list(bquote(`+`), re_list[1:2])), re_list[-(1:2)])
  as.call(list(bquote(`+`), re_list[[1]], re_list[[2]]))
}

所以现在很简单:

get_random_effects(mymodel)
#> (1 | fac1) + (1 | fac2)

您可以使用insight-package访问各种 model 信息,例如公式、预测变量、数据等。insight提供适用于许多不同模型的类型安全“泛型”。 在这种情况下,您可以使用find_formula()find_random()

library(insight)
library(lme4)
data(sleepstudy)
sleepstudy$mygrp <- sample(1:5, size = 180, replace = TRUE)
sleepstudy$mysubgrp <- NA
for (i in 1:5) {
  filter_group <- sleepstudy$mygrp == i
  sleepstudy$mysubgrp[filter_group] <-
    sample(1:30, size = sum(filter_group), replace = TRUE)
}

m <- lmer(
  Reaction ~ Days + (1 | mygrp / mysubgrp) + (1 | Subject),
  data = sleepstudy
)
#> boundary (singular) fit: see ?isSingular

find_formula(m)
#> $conditional
#> Reaction ~ Days
#> 
#> $random
#> $random[[1]]
#> ~1 | mysubgrp:mygrp
#> 
#> $random[[2]]
#> ~1 | mygrp
#> 
#> $random[[3]]
#> ~1 | Subject

find_random(m)
#> $random
#> [1] "mysubgrp:mygrp" "mygrp"          "Subject"       
#> 

find_random(m, split_nested = TRUE)
#> $random
#> [1] "mysubgrp" "mygrp"    "Subject" 

find_random(m, split_nested = TRUE, flatten = TRUE)
#> [1] "mysubgrp" "mygrp"    "Subject" 

find_formula()find_random()也适用于具有随机效应的零膨胀部分的模型,例如来自glmmTMBbrms包的模型。 找到可能的随机斜率的“对应物”是find_random_slopes()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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