使用purrr::map()调用lmer()正常,调用nlme::lme()报".x未找到"错误
使用purrr::map()调用nlme::lme()时出现'.x'未找到的错误
运行nlme::lme()时收到如下错误:
Error in `map()`: ℹ In index: 1. ℹ With name: p_h. Caused by error: ! object '.x' not found
测试数据
testdata <- structure(list(subject = c("B001", "B001", "B001", "B001", "B001", "B002", "B002", "B002", "B002", "B002", "B003", "B003", "B003", "B003", "B003", "B004", "B004", "B004", "B004", "B004", "B005", "B005", "B005", "B005", "B005"), time_point = structure(c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), levels = c("Wk0", "Wk4", "Wk8", "Wk12", "Wk16"), class = "factor"), sfa = c(62.895, 84.705, 83.49, 66.64, 72.19, 56.195, 93.945, 92.635, 88.51, 83.505, 92.67, 90.81, 83.37, 90.205, 84.195, 88.065, 53.69, 93.14, 52.57, 95.995, 63.505, 92.59, 80.87, 89.125, 67.305), mufa = c(14.455, 11.71, 12.58, 21.135, 26.175, 13.285, 4.91, 6.08, 6.735, 12.745, 7.325, 7.605, 15.735, 7.985, 12.32, 7.92, 42.045, 4.57, 24.305, 4.505, 18.585, 5.955, 14.815, 8.775, 20.295), pufa = c(22.65, 3.58, 3.935, 12.23, 1.635, 30.525, 1.135, 1.275, 4.76, 3.75, 0, 1.595, 0.885, 1.82, 3.495, 4.01, 4.26, 2.29, 23.125, 0, 17.905, 1.455, 4.305, 2.1, 12.4)), row.names = c(NA, -25L), class = c("tbl_df", "tbl", "data.frame" ))
可正常运行的lmer()代码
library(lme4) library(nlme) library(lmerTest) library(broom.mixed) testdata |> dplyr::select(sfa, mufa, pufa) |> purrr::map(~ lmer(.x ~ time_point + (1| subject), data = testdata))
出错的nlme::lme()代码
library(lme4) library(nlme) library(lmerTest) library(broom.mixed) testdata |> dplyr::select(sfa, mufa, pufa) |> purrr::map(~ lme(.x ~ time_point, random = ~ 1 | subject, data = testdata, method = 'ML'))
问题原因
lme()和lmer()的公式解析逻辑存在差异:
lmer()允许直接引用环境中的对象(比如map()传入的.x向量)lme()会严格在data参数指定的数据框内查找变量,无法识别环境中的.x
解决方案
方法1:用reformulate()动态构建公式
针对每个因变量生成对应的公式,确保lme()能在数据框中找到变量:
testdata |> dplyr::select(sfa, mufa, pufa) |> purrr::imap(function(.x, .y) { lme(reformulate("time_point", response = .y), random = ~1 | subject, data = testdata, method = "ML") })
方法2:临时重命名因变量
遍历变量名,将当前因变量重命名为统一名称后再建模:
c("sfa", "mufa", "pufa") |> purrr::map(function(var) { testdata |> dplyr::mutate(y = .data[[var]]) |> lme(y ~ time_point, random = ~1 | subject, data = _, method = "ML") }) |> purrr::set_names(c("sfa", "mufa", "pufa"))
方法3:传递变量名而非向量
直接遍历变量名字符串,在公式中使用变量名:
testdata |> dplyr::select(sfa, mufa, pufa) |> names() |> purrr::map(function(var) { lme(as.formula(paste(var, "~ time_point")), random = ~1 | subject, data = testdata, method = "ML") }) |> purrr::set_names(c("sfa", "mufa", "pufa"))
内容的提问来源于stack exchange,提问作者KIM
相关产品推荐
相关产品推荐

