具有 4 个级别的多级模型?

机器算法验证 r 混合模式 lme4-nlme 多层次分析 随机效应模型
2022-04-09 18:58:13

我的数据集是一个非常典型的教育数据集:我们有关于学生、课程、教师、学校的数据,我计划包括部分交叉的随机效应,因为学生可以注册同一教员的多门课程或多位教员的课程.

除了学校(学校 n = 22)之外,我在所有级别都有预测器。四级模型是否理想?还是应该运行一个三级模型并将学校数据作为固定虚拟变量包含在内?

我的理解是我不能将 lme4 用于四级模型——所以如果我应该用四级对数据进行建模,有哪些软件包可以帮助我这样做?

1个回答

中的“级别”数量没有限制lme4只要数据支持这种随机效应结构,该包将能够适应任意数量的级别。

我们可以通过以下模拟来演示类似于 OP 中描述的 4 级数据集:

> set.seed(15)
> library(lme4)
> dt1 <- data.frame(expand.grid(SchoolID = LETTERS[1:6], FacultyID = LETTERS[1:6], CourseID = LETTERS[1:10], StudentID = 1:100, Score = c(NA, NA, NA)))
> dt1$Score <- as.numeric(dt1$SchoolID) + as.numeric(dt1$FacultyID) + as.numeric(dt1$CourseID) + as.numeric(dt1$StudentID) + rnorm(nrow(dt1), 0,5)
> lmm1 <- lmer(Score ~ 1 + (1 | SchoolID/FacultyID/CourseID/StudentID), data = dt1)
> summary(lmm1)  
Random effects:
 Groups                                    Name        Variance Std.Dev.
 StudentID:(CourseID:(FacultyID:SchoolID)) (Intercept) 841.6574 29.0113 
 CourseID:(FacultyID:SchoolID)             (Intercept)   0.8581  0.9263 
 FacultyID:SchoolID                        (Intercept)   2.5579  1.5993 
 SchoolID                                  (Intercept)   2.8880  1.6994 
 Residual                                               24.9743  4.9974 
Number of obs: 108000, groups:  
StudentID:(CourseID:(FacultyID:SchoolID)), 36000; CourseID:(FacultyID:SchoolID), 360; FacultyID:SchoolID, 36; SchoolID, 6

如果我们愿意,我们也可以拟合一个 5 层模型:

> dt2 <- data.frame(expand.grid(CityID = LETTERS[1:6], SchoolID = LETTERS[1:6], FacultyID = LETTERS[1:6], CourseID = LETTERS[1:10], StudentID = 1:20, Score = c(NA, NA, NA)))
> dt2$Score <- as.numeric(dt2$CityID) + as.numeric(dt2$SchoolID) + as.numeric(dt2$FacultyID) + as.numeric(dt2$CourseID) + as.numeric(dt2$StudentID) + rnorm(nrow(dt2), 0, 5)
> lmm2 <- lmer(Score ~ 1 + (1 | CityID/SchoolID/FacultyID/CourseID/StudentID), data = dt2)
> summary(lmm2)  
Random effects:
 Groups                                             Name        Variance 
Std.Dev.
 StudentID:(CourseID:(FacultyID:(SchoolID:CityID))) (Intercept) 34.778   5.897   
 CourseID:(FacultyID:(SchoolID:CityID))             (Intercept)  7.418   2.724   
 FacultyID:(SchoolID:CityID)                        (Intercept)  2.516   1.586   
 SchoolID:CityID                                    (Intercept)  2.873   1.695   
 CityID                                             (Intercept)  2.922   1.709   
 Residual                                                       24.940   4.994   
Number of obs: 129600, groups:  
StudentID:(CourseID:(FacultyID:(SchoolID:CityID))), 43200; CourseID:(FacultyID:(SchoolID:CityID)), 2160; FacultyID:(SchoolID:CityID), 216; SchoolID:CityID, 36; CityID, 6

[请注意,第二个模型可能需要一段时间才能适应!]

部分交叉结构最好通过确保每个簇中的因子被唯一编码来表示,lme4然后应该能够通过将随机效应指定为简单地处理部分交叉/部分嵌套结构

(1 | SchoolID) + (1 | FacultyID) + (1 | CourseID) + (1 | StudentID)

这意味着,例如,如果你有 StudentID 1inFaculty AStudent 1inFaculty B并且它们是不同的(即这两个学生嵌套在各自的院系中),那么它们应该分别编码为类似StudentID 1AStudentID 1B我们可以用dt1上面的数据集证明这一点,通过重新编码如下因素:

> dt1.1 <- dt1
> dt1.1$FacultyID <- paste(dt1$SchoolID, dt1$FacultyID, sep = ".")
> dt1.1$CourseID <- paste(dt1.1$FacultyID, dt1$CourseID, sep = ".")
> dt1.1$StudentID <- paste(dt1.1$CourseID, dt1$StudentID, sep = ".")
> lmm1.1 <- lmer(Score ~ 1 + (1 | SchoolID) + (1 | FacultyID) + (1 | CourseID) + (1 | StudentID), data = dt1.1)
> summary(lmm1.1)  

Random effects:
 Groups    Name        Variance Std.Dev.
 StudentID (Intercept) 841.6568 29.0113 
 CourseID  (Intercept)   0.8584  0.9265 
 FacultyID (Intercept)   2.5585  1.5995 
 SchoolID  (Intercept)   2.8893  1.6998 
 Residual               24.9743  4.9974 
Number of obs: 108000, groups:  StudentID, 36000; CourseID, 360; FacultyID, 36; SchoolID, 6

请注意,模型输出与lmm1上述相同,尽管呈现方式略有不同。

到目前为止,数据是完全嵌套的。也就是说,每个学生只注册一门课程,一门课程“属于”一门学院等。为了模拟交叉因素,例如注册两门课程的学生,我们可以简单地结合相关的学生 ID:首先我们确定要组合的学生 ID:

> dt1.1[dt1.1$StudentID == "A.A.A.31" | dt1.1$StudentID == "A.A.B.31", ]
      SchoolID FacultyID CourseID StudentID    Score
10801        A       A.A    A.A.A  A.A.A.31 33.00600
10837        A       A.A    A.A.B  A.A.B.31 33.69633
46801        A       A.A    A.A.A  A.A.A.31 33.03089
46837        A       A.A    A.A.B  A.A.B.31 33.00802
82801        A       A.A    A.A.A  A.A.A.31 41.68804
82837        A       A.A    A.A.B  A.A.B.31 31.26155

并给他们相同的(唯一的)ID:

> dt1.1[dt1.1$StudentID == "A.A.A.31" | dt1.1$StudentID == "A.A.B.31", ]$StudentID   <- "CCCC"

然后我们可以用相同的调用来拟合模型:

lmm1.1 <- lmer(Score ~ 1 + (1 | SchoolID) + (1 | FacultyID) + (1 | CourseID) + (1 | StudentID), data = dt1.1)
> summary(lmm1.1)  
Random effects:
 Groups    Name        Variance Std.Dev.
 StudentID (Intercept) 841.6867 29.0118 
 CourseID  (Intercept)   0.8312  0.9117 
 FacultyID (Intercept)   2.5570  1.5991 
 SchoolID  (Intercept)   2.8851  1.6986 
 Residual               24.9742  4.9974 
Number of obs: 108000, groups:  StudentID, 35999; CourseID, 360; FacultyID, 36; SchoolID, 6

请注意,我们现在有 35,999StudentID秒,而不是 36,000 秒。

有关编码交叉和嵌套因子的更多信息,请参见此处