如何避免使用do.call()调用模型时,返回的call对象打印数据框的全部条目?
如何避免使用do.call()调用模型时,返回的call对象打印数据框的全部条目?
这个问题我之前也碰到过,用do.call()调用模型时,参数里的数据框会被完全展开到call输出里,导致日志或控制台输出特别冗长,确实挺闹心的。其实不用手动修改模型的call槽(你说的把它改成字符串的方式确实不太稳妥,因为原本的call是R的语言对象,改成字符串后后续可能没法正常用于模型更新、参数提取等操作),有更优雅的原生解决办法:
方法一:用quote()包裹数据框参数
在构造do.call的参数列表时,用quote()把数据框的引用包起来,这样do.call就会保留数据框的符号名,而不是展开它的全部内容:
library(randomForest) data(iris) # 用quote()包裹data参数 mod <- do.call(randomForest, list(Species ~ ., data = quote(iris))) # 查看call输出 mod$call #> randomForest(formula = Species ~ ., data = iris)
原理是quote()会阻止R对参数进行求值,所以传递给do.call的是iris这个符号本身,而不是它的实际数据内容,这样模型的call就会和直接调用randomForest(Species ~ ., data=iris)的结果一致。
方法二:用substitute()构建完整调用表达式
如果你的参数更复杂,也可以用substitute()先构建好完整的调用表达式,再用eval()执行,这样能更灵活地控制参数的符号引用:
# 构建调用表达式 call_expr <- substitute( randomForest(formula_arg, data = data_arg), list(formula_arg = Species ~ ., data_arg = quote(iris)) ) # 执行表达式得到模型 mod <- eval(call_expr) # 查看call输出 mod$call #> randomForest(formula = Species ~ ., data = iris)
这种方法适合参数较多或者需要动态生成参数名的场景,同样能保证call里保留数据框的原始符号名。
为什么手动修改call槽不推荐?
你之前尝试把mod$call改成字符串的方式,会把原本的语言对象变成字符型,后续如果需要用update()更新模型,或者用其他依赖call结构的函数时,很可能会报错——因为这些函数期望call是可解析的R语言对象,而不是字符串。
备注:内容来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

