我正在创建一个使用non-standard evaluation来跟踪列含义的包。该包在函数之间传递数据框,这些函数执行各种操作,执行相同的列集。非标准评估对此非常有用:
my_select <- function(df, xcol, ycol) {
new_df <- dplyr::select(df, !!xcol, !!ycol)
new_df
}
my_select(mtcars, quo(wt), quo(mpg))
但是,我喜欢使用公式的函数:
my_lm <- function(df, xcol, ycol) {
new_lm <- lm(!!xcol, !!ycol, data=df)
new_lm
}
my_lm(mtcars, quo(wt), quo(mpg)
返回Error in !xcol : invalid argument type
。我已经尝试了quo()
,enquo()
和!!
的各种组合,但基本问题是我不知道什么样的对象{{1需要。
答案 0 :(得分:1)
您可以通过将等式的值粘贴在一起来创建公式,然后将公式传递给lm
。我确信有更好的方法可以做到这一点,但这是一种有效的方法:
library(rlang)
my_lm <- function(df, xcol, ycol) {
form <- as.formula(paste(ycol, " ~ ", xcol)[2])
my_lm <- lm(form, data=df)
my_lm
}
my_lm(mtcars, quo(wt), quo(mpg))
#>
#> Call:
#> lm(formula = form, data = mtcars)
#>
#> Coefficients:
#> (Intercept) wt
#> 37.285 -5.344
答案 1 :(得分:1)
@zlipp提供了一个有效的答案,但这是一个更新的版本
my_lm <- function(df, xcol, ycol) {
xcol_e <- rlang::enquo(xcol)
ycol_e <- rlang::enquo(ycol)
form <- paste0(rlang::as_label(ycol_e), "~", rlang::as_label(xcol_e))
new_lm <- lm(form, data=df)
new_lm
}
my_lm(mtcars, wt, mpg)
my_lm <- function(.df, xcol, ycol) {
form <- rlang::new_formula(rlang::ensym(ycol), rlang::ensym(xcol))
new_lm <- lm(form, data=.df)
new_lm
}
my_lm(mtcars, wt, mpg)