如何将call对象传入do.call?ranger函数参数调用报错解决
解决ranger函数do.call调用时的sample.fraction参数报错问题
问题原因
formals(ranger)返回的sample.fraction默认值是一个未求值的表达式:ifelse(classification, 1, 0.632)。这个表达式原本是设计在ranger函数内部求值的(依赖函数内部的classification参数,该参数由输入的数据和公式自动判断),但当你通过do.call直接传递这个表达式时,它会在当前全局环境中尝试执行,而全局环境中不存在classification变量,因此触发类型转换错误。
另外你的代码中lParams$data<-substitute(iris)也存在问题:substitute(iris)返回的是符号对象,而非实际的数据集,ranger需要接收数据框对象作为data参数,这也可能导致潜在问题。
解决方案
方案1:移除sample.fraction参数,让函数自动使用默认值
如果不需要修改sample.fraction的默认值,直接从参数列表中移除该参数,让ranger函数内部自行计算默认值即可:
library(ranger) # 获取ranger的所有形式参数并转为列表 lParams <- as.list(formals(ranger)) # 修改目标参数 lParams$formula <- as.formula("Species~.") lParams$data <- iris # 直接传递数据集对象,而非符号 lParams[["..."]] <- NULL # 移除sample.fraction参数,交由函数内部处理默认值 lParams[["sample.fraction"]] <- NULL # 调用函数 do.call("ranger", lParams)
方案2:手动设置sample.fraction的具体值
如果你想明确传递默认值,可根据任务类型(分类/回归)直接设置对应数值。对于当前的分类任务(Species是分类变量),默认值为1:
library(ranger) lParams <- as.list(formals(ranger)) lParams$formula <- as.formula("Species~.") lParams$data <- iris lParams[["..."]] <- NULL # 手动设置分类任务的sample.fraction默认值 lParams$sample.fraction <- 1 do.call("ranger", lParams)
方案3:让表达式在ranger函数环境中求值(进阶)
如果你希望保留原表达式的逻辑,可通过eval在ranger的函数环境中预先计算该值:
library(ranger) lParams <- as.list(formals(ranger)) lParams$formula <- as.formula("Species~.") lParams$data <- iris lParams[["..."]] <- NULL # 在ranger的函数环境中计算sample.fraction的默认值 # 先判断当前任务是否为分类 classification <- is.factor(iris$Species) lParams$sample.fraction <- eval(lParams$sample.fraction, list(classification = classification)) do.call("ranger", lParams)
内容的提问来源于stack exchange,提问作者Lev
相关产品推荐
相关产品推荐

