You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传入Formula参数时,lapply结合lm估计复权模型报错问题

复权回归模型函数报错问题

问题背景

我想用复权(replicate weights)估计回归模型,通过每组复权跑同一模型来得到正确的标准误。为避免重复编写循环,我写了两个函数:trythis在lapply内直接指定公式可正常运行,但将公式作为参数传入的trythis2却报错,提示object 'weightsdata' not found。

可复现代码

数据生成代码

library(tidyverse)
set.seed(123)
lm.dat <- data.frame(id=1:500,
                     x1=sample(1:100, replace=T, size=500),
                     x2=runif(n=500, min=0, max=20)) %>%
  mutate(y=0.2*x1+1.5*x2+rnorm(n=500, mean=0, sd=5))
repweights <- data.frame(id=1:500)
set.seed(123)
for (i in 1:200) {
  repweights[,i+1] <- runif(n=500, min=0, max=10)
  names(repweights)[i+1] <- paste0("hrwgt", i)
}

函数定义

trythis <- function(data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) lm(data=data, formula=y~x1+x2, weights=weightsdata[,x]))
  return(res)
}
results1 <- trythis(data=lm.dat, weightsdata=repweights[-1], weightsN=200)

trythis2 <- function(LMformula, data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) lm(data=data, formula=LMformula, weights=weightsdata[,x]))
  return(res)
}

报错情况

调用trythis2时出现以下错误:

trythis2(LMformula = y~x1+x2, data=lm.dat, weightsN=200, weightsdata = repweights[-1])
# Error in eval(extras, data, env) : object 'weightsdata' not found

问题原因

这是公式的环境绑定问题:当你把LMformula作为参数传入函数时,它的环境是全局环境(或调用trythis2的外部环境);而lapply内的匿名函数执行时,lm会尝试在公式绑定的环境中查找weightsdata,但weightsdata是trythis2的局部变量,不在公式的环境范围内,因此找不到。

而trythis里直接写y~x1+x2,这个公式是在trythis函数内部创建的,环境绑定到trythis的函数环境,所以能正常找到weightsdata。

解决方案

方法1:重新绑定公式的环境

将传入的LMformula的环境设置为当前函数的环境,让lm能找到局部变量weightsdata:

trythis2 <- function(LMformula, data, weightsdata, weightsN){
  # 把公式的环境绑定到当前函数环境
  environment(LMformula) <- environment()
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) lm(data=data, formula=LMformula, weights=weightsdata[,x]))
  return(res)
}

方法2:将权重临时加入数据框

每次迭代把当前权重列加入到输入数据中,直接用列名指定权重,避开环境查找问题:

trythis2 <- function(LMformula, data, weightsdata, weightsN){
  rep <- as.list(1:weightsN)
  res <- lapply(rep, function(x) {
    # 将当前权重临时加入数据框
    temp_data <- cbind(data, w = weightsdata[,x])
    lm(data=temp_data, formula=LMformula, weights=w)
  })
  return(res)
}

两种方法均可正常运行,生成包含200个回归模型的结果列表。


内容的提问来源于stack exchange,提问作者andreasf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:15:43