如何用rlang包的{{}}/!!/inject()实现支持NSE的自定义mylm函数?
用rlang非标准求值实现自定义mylm函数
你之前的写法错误在于没有正确构造lm所需的公式对象,lm的第一个参数必须是形如y ~ x的公式,而非单独传入响应变量和预测变量。以下是用{{}}、!!或inject()实现的正确版本:
方法1:用{{}}直接构造公式
library(rlang) mylm <- function(y, x, data) { lm({{ y }} ~ {{ x }}, data = data) } # 测试,效果和lm(cyl~mpg, data=mtcars)完全一致 mylm(cyl, mpg, data = mtcars)
方法2:用enquo()和!!引用表达式
library(rlang) mylm <- function(y, x, data) { # 捕获传入的表达式 y_quo <- enquo(y) x_quo <- enquo(x) # 用!!插入到公式中 lm(!!y_quo ~ !!x_quo, data = data) } mylm(cyl, mpg, data = mtcars)
方法3:用inject()配合{{}}
library(rlang) mylm2 <- function(y, x, data) { inject(lm({{ y }} ~ {{ x }}, data = data)) } mylm2(cyl, mpg, data = mtcars)
错误原因说明
你之前的代码没有将y和x组合成公式,而是直接作为lm的前两个参数传递:
lm的第一个参数如果不是公式,会被当作响应变量,第二个参数会被解析为数据对象,导致程序误以为mpg是数据框,进而找不到cyl或者出现下标类型错误。
内容的提问来源于stack exchange,提问作者zhiwei li
相关产品推荐
相关产品推荐

