2017-10-21 52 views
1

我想寫使用tidyeval(非標準評價)。採用基礎R NSE圍繞「LM」的功能,它的工作原理:編程使用「LM」功能tidyeval

lm_poly_raw <- function(df, y, x, degree = 1, ...){ 
    lm_formula <- 
    substitute(expr = y ~ poly(x, degree, raw = TRUE), 
       env = list(y = substitute(y), 
          x = substitute(x), 
          degree = degree)) 
    eval(lm(lm_formula, data = df, ...)) 
} 

lm_poly_raw(mtcars, hp, mpg, degree = 2) 

然而,我還沒有想出如何使用tidyevalrlang來編寫這個函數。我認爲substitute應該被替換爲enquo,並且由!!來評估。 Hadley的Adv-R中有一些提示,但我無法弄清楚。

+0

爲什麼要這樣做? – Thomas

+0

爲了用dplyr函數編程,它對usw tidyeval/rlang很有用,我只想使用一個系統。 Beides,我想向一些Studenten Nse解釋,我認爲只使用一個系統更容易,更一致。 –

+0

鑑於lm()不使用與dplyr相同的NSE形式,我不認爲用rlang打它會有幫助。 – Thomas

回答

3

這裏是那種式構造,可能使它的方式在rlang的未來:

f <- function(x, y, flatten = TRUE) { 
    x <- enquo(x) 
    y <- enquo(y) 

    # Environments should be the same 
    # They could be different if forwarded through dots 
    env <- get_env(x) 
    stopifnot(identical(env, get_env(y))) 

    # Flatten the quosures. This warns the user if nested quosures are 
    # found. Those are not supported by functions like lm() 
    if (flatten) { 
    x <- quo_expr(x, warn = TRUE) 
    y <- quo_expr(y, warn = TRUE) 
    } 

    new_formula(x, y, env = env) 
} 

# This can be used for unquoting symbols 
var <- "cyl" 
lm(f(disp, am + (!! sym(var))), data = mtcars) 

棘手的部分是:

  • 的LHS和RHS可能來自不同的環境如果通過...的不同層次轉發。我們需要檢查這一點。

  • 我們需要檢查用戶是否沒有引用問題。 lm()和co不支持這些。 quo_expr()展平所有問題,並在發現某些情況時選擇發出警告。

+0

謝謝,那就是我一直在尋找的。仍然需要包裹我的頭,雖然:) –