【问题标题】:In R, how to use update() dynamically?在 R 中,如何动态使用 update()?
【发布时间】:2026-02-12 23:35:01
【问题描述】:

在 R 中,我经常需要遍历 lm 类型对象的列表(例如 glmlmeclm)并使用新公式或其他参数更新它们。我使用lapply() 执行此操作,因为它以相同的列表格式返回它们,名称不变,因此我可以继续该过程。

有时我传递的参数是动态的,并且因每个模型而异。例如,

lapply(names(mylist) function(ii) {
  jj<-myotherlist[[ii]]; 
  update(mylist[[ii]],.~.+jj)
}) 

其中jj 是添加到列表中每个模型的术语,并在其他列表中基于每个模型进行定义。

假设特定模型的预期结果公式应该是y~a+b+c。取而代之的是,生成的lm 对象内的调用对象包含y~a+b+jj。因此,在某些情况下,生成的 lm 对象表现正常,但每当需要计算公式时,它就会出错,因为 jj 早已不复存在。是否有推荐的方法来强制update() 在其输出中写入call 对象时扩展其参数中的所有变量,或者强制使用call 对象的函数评估lm 中的调用对象的内部上下文而不是全局上下文,这样至少我可以将新变量填充到lm 样式对象通常包含的modeldata 对象中?

而且,如果使用动态变量更新的部分是数据参数怎么办?例如:

data=cbind(sharedByAllModels,y=kk)

...kk 对当前模型是唯一的(可能是 sharedByAllModels 数据帧中某些列的某种聚合)。

【问题讨论】:

    标签: r lm


    【解决方案1】:

    回答您的主要问题后,您可以使用bquote() 来控制更新公式对象的哪些部分(即.() 中的部分)得到评估。

    mylist <- list(y ~ a + b, y ~ A + B)
    myotherlist <- list("c", "C")
    
    lapply(1:2, function(ii) {
        jj <- as.name(myotherlist[[ii]])
        update(mylist[[ii]], bquote(. ~ . + .(jj)))})
    # [[1]]
    # y ~ a + b + c
    # 
    # [[2]]
    # y ~ A + B + C
    

    或者,以类似的方式使用substitute()

    lapply(1:2, function(ii) {
          jj <- as.name(myotherlist[[ii]])
          update(mylist[[ii]], substitute(. ~ . + jj))
          })
    # [[1]]
    # y ~ a + b + c
    # 
    # [[2]]
    # y ~ A + B + C
    

    【讨论】:

      【解决方案2】:

      使用do.call,它会在执行前评估其参数。见anova test fails on lme fits created with pasted formula

      【讨论】: