R6类调用stats::lm()时weights与subset参数无法识别问题求助
R6类中调用stats::lm()时weights/subset变量找不到的问题解决
问题原因
当调用stats::lm()并指定data参数时,函数会默认在data对应的环境中解析weights和subset参数,而非当前R6方法的局部函数环境。你在方法内定义的weight_vec和subset_vec属于局部变量,不在private$data的环境中,因此lm无法找到这些变量。
方案1:临时将变量加入data中(推荐)
直接把权重或子集向量临时添加到private$data中,让lm能在指定数据集里找到对应变量,用完后再删除临时列避免污染数据:
gen_reg_data <- R6::R6Class( classname = "regressionClass", public = list( initialize = function(data){ private$data <- data }, lm = function(formula){ stats::lm(formula = formula, data = private$data) }, weighted_lm = function(formula, weight_col){ # 临时添加权重列到data private$data$.temp_weight <- abs(private$data[, weight_col]) print(head(private$data$.temp_weight)) result <- tryCatch( stats::lm(formula = formula, weights = .temp_weight, data = private$data), error = function(e) e ) # 用完删除临时列 private$data$.temp_weight <- NULL result }, subset_lm = function(formula){ # 临时添加子集列到data private$data$.temp_subset <- private$data$X10 >= 0 print(head(private$data$.temp_subset)) result <- tryCatch( stats::lm(formula = formula, subset = .temp_subset, data = private$data), error = function(e) e ) # 删除临时列 private$data$.temp_subset <- NULL result } ), private = list( data = NULL ) )
方案2:手动指定lm的求值环境
将公式的环境设置为当前方法的局部环境,让lm优先在局部环境中查找变量:
gen_reg_data <- R6::R6Class( classname = "regressionClass", public = list( initialize = function(data){ private$data <- data }, lm = function(formula){ stats::lm(formula = formula, data = private$data) }, weighted_lm = function(formula, weight_col){ weight_vec <- abs(private$data[, weight_col]) print(head(weight_vec)) # 将公式的环境设置为当前函数环境 formula_obj <- as.formula(formula) environment(formula_obj) <- environment() tryCatch( stats::lm(formula = formula_obj, weights = weight_vec, data = private$data), error = function(e) e ) }, subset_lm = function(formula){ subset_vec <- private$data$X10 >= 0 print(head(subset_vec)) formula_obj <- as.formula(formula) environment(formula_obj) <- environment() tryCatch( stats::lm(formula = formula_obj, subset = subset_vec, data = private$data), error = function(e) e ) } ), private = list( data = NULL ) )
方案3:使用with()包裹lm调用
通过with()函数将data环境和局部环境结合,让lm能同时访问data和局部变量:
gen_reg_data <- R6::R6Class( classname = "regressionClass", public = list( initialize = function(data){ private$data <- data }, lm = function(formula){ stats::lm(formula = formula, data = private$data) }, weighted_lm = function(formula, weight_col){ weight_vec <- abs(private$data[, weight_col]) print(head(weight_vec)) tryCatch( with(private$data, stats::lm(formula = formula, weights = weight_vec)), error = function(e) e ) }, subset_lm = function(formula){ subset_vec <- private$data$X10 >= 0 print(head(subset_vec)) tryCatch( with(private$data, stats::lm(formula = formula, subset = subset_vec)), error = function(e) e ) } ), private = list( data = NULL ) )
内容的提问来源于stack exchange,提问作者Zhenning
相关产品推荐
相关产品推荐

