Koenker quantreg包rq函数weights参数函数内调用问题求助
解决quantreg::rq在自定义函数中weights参数的作用域问题
在实现加权bootstrap时,quantreg包的rq()函数在自定义函数内部使用weights参数会出现变量查找失败的问题:只有当权重对象存在于全局环境时才能生效,直接传入函数参数则报错找不到对象。
问题复现
rm(list=ls()) library(quantreg) set.seed(10983) N = 500 K = 2 B = array(1, dim=c(K,1)) X = array(rnorm(N*K), dim=c(N,K)) e = array(rnorm(N), dim=c(N,1)) Y = X%*%B + e df = cbind.data.frame(Y, X) names(df) = c('Y', paste('X', 1:K, sep='')) # 全局环境下正常运行 Zs = array(rexp(N), dim=c(N,1)) ws = Zs / sum(Zs) mdl2 = rq(Y ~ 1 + X1 + X2, data=df, tau=-1, weights=N*ws) # 自定义函数内调用则报错 estimate = function(Y, X, W){ df = cbind.data.frame(Y, X) names(df) = c('Y', paste('X', 1:K, sep='')) eqn = paste('Y ~ 1 +', paste(names(df)[-1], collapse=' + ')) mdl = rq(formula=eqn, data=df, tau=-1, weights=W) return(mdl$sol[,100]) } # 执行报错:找不到对象'W' estimate(Y,X,ws*N)
问题原因
rq()的weights参数默认会在全局环境或者data参数指定的data.frame中查找变量,不会自动识别函数的局部环境。当在自定义函数中传入W作为参数时,rq()无法在自身的查找路径中找到这个局部变量,因此报错。
优化解决方案
方案1:将权重加入到data.frame中
把权重向量作为新列加入到函数内构建的data.frame中,这样rq()可以从data参数中找到权重变量:
estimate = function(Y, X, W){ # 将权重加入data.frame df = cbind.data.frame(Y, X, bootstrap_weights = W) names(df)[1:3] = c('Y', paste('X', 1:K, sep='')) eqn = paste('Y ~ 1 +', paste(names(df)[-c(1,ncol(df))], collapse=' + ')) # weights参数使用data.frame中的列名 mdl = rq(formula=eqn, data=df, tau=-1, weights=bootstrap_weights) return(mdl$sol[,100]) } # 正常执行 estimate(Y,X,ws*N)
方案2:显式指定变量查找环境
rq()支持environment参数,通过指定为当前函数的局部环境,让函数能找到传入的权重参数:
estimate = function(Y, X, W){ df = cbind.data.frame(Y, X) names(df) = c('Y', paste('X', 1:K, sep='')) eqn = paste('Y ~ 1 +', paste(names(df)[-1], collapse=' + ')) # 显式设置环境为当前函数的局部环境 mdl = rq(formula=eqn, data=df, tau=-1, weights=W, environment = environment()) return(mdl$sol[,100]) } # 正常执行 estimate(Y,X,ws*N)
这两种方案都不需要修改原始数据结构或手动构造常数项,完全保留rq()函数的原生用法,比临时解决方案更简洁合理。
内容的提问来源于stack exchange,提问作者Stéphane
相关产品推荐
相关产品推荐

