R语言:model.frame可选weights参数传递错误及变量提取优化
问题解决与优化方案
一、错误原因及修复
触发错误的核心原因有两个:
- 参数名不匹配:函数定义的参数是
weights,但调用时写成了weight=wt,导致函数内的weights参数未被赋值,默认指向R内置的weights()函数(闭包类型),从而抛出"invalid type (closure)"错误。 - 变量作用域问题:直接传
wt时,函数内部无法找到这个对象——它属于dtaw数据框,而非函数的运行环境。
快速修复调用方式
修正参数名,并正确传递权重列的向量:
test(ff, weights=dtaw$wt, data=dtaw)
更鲁棒的函数实现(支持直接传列名)
如果希望直接传入列名而非向量,可通过非标准求值处理参数,让调用更简洁:
test <- function(ff, weights, data) { wt_call <- substitute(weights) mm <- model.frame(ff, data, weights = eval(wt_call, data, parent.frame())) y <- model.response(mm) # 优化提取右侧变量的逻辑(见下文) rhs_terms <- attr(terms(ff), "term.labels") x <- mm[[rhs_terms[1]]] w <- mm[, rhs_terms[-1], drop=FALSE] wt <- model.weights(mm) mat <- cbind(y, x, w, wt) return(sum(mat)) } # 调用时直接传列名即可 test(ff, weights=wt, data=dtaw)
二、优化model.frame右侧变量提取方法
不要依赖固定列索引(如mm[,2])——model.frame的列顺序可能因公式结构、数据变化而改变,更可靠的方式是基于公式的terms属性提取变量:
- 获取公式右侧的所有变量名:
rhs_terms <- attr(terms(ff), "term.labels")
这里会返回公式右侧的变量名列表(示例中为c("x", "w1", "w2"))
- 提取第一个右侧变量:
x <- mm[[rhs_terms[1]]]
- 提取剩余的右侧变量:
w <- mm[, rhs_terms[-1], drop=FALSE]
添加drop=FALSE可保证结果始终为数据框,避免只剩一个变量时自动转为向量。
这种提取方式完全基于公式结构,不受列顺序影响,稳定性更强。
内容的提问来源于stack exchange,提问作者amrods
相关产品推荐
相关产品推荐

