簡體   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