使用lapply对嵌套列表执行lmer函数报错,求解决方法
问题原因
你报错的核心原因有两个:
- 公式写法错误:
lmer会在data参数指定的数据框内查找变量,你写的x[,4:7]试图在数据框外部引用对象,而数据框中并没有名为x的列,R只能去外层环境找x,但外层的x是列表类型,不符合模型要求。 - 变量名冲突:内层
lapply的参数名用了x,和外层的x重名,容易导致变量解析混乱。
解决方案
下面用嵌套列表场景,结合可复现代码给出两种解决思路:
前提:构建可复现的嵌套列表
先基于mtcars构建和你场景一致的嵌套列表list3:
library(lme4) # 构建两层嵌套列表 list3 <- list( group1 = list(sub1 = mtcars[1:10, ], sub2 = mtcars[11:20, ]), group2 = list(sub1 = mtcars[21:32, ], sub2 = mtcars[1:15, ]) )
思路1:对每个响应列单独拟合模型
如果要给每个子数据框的每一列(比如第3到7列)分别拟合模型,需要再嵌套一层循环遍历响应列:
# 遍历嵌套列表,逐个拟合单响应混合模型 model_results <- lapply(list3, function(group_data) { lapply(group_data, function(sub_df) { # 提取目标响应列的列名 resp_col_names <- colnames(sub_df)[3:7] # 对每个响应列单独建模 lapply(resp_col_names, function(resp_col) { # 动态构建公式 model_formula <- as.formula(paste(resp_col, "~ vs + (1|cyl)")) lmer(model_formula, data = sub_df) }) }) })
思路2:拟合多响应混合模型
如果要同时对多个响应列拟合多响应混合模型,用cbind()把响应列组合起来即可:
# 拟合多响应混合模型 multi_resp_results <- lapply(list3, function(group_data) { lapply(group_data, function(sub_df) { lmer(cbind(disp, hp, drat, wt, qsec) ~ vs + (1|cyl), data = sub_df) }) })
额外提示
- 尽量避免函数参数名和数据框列名、外层变量名重名,比如把内层函数参数从
x改成sub_df,代码可读性更强,也能避免变量解析错误。 - 如果你的
var、id是数据框中的列名,直接在公式里写列名即可,不要用x[,n]这种外部引用的写法。
内容的提问来源于stack exchange,提问作者12666727b9
相关产品推荐
相关产品推荐

