2017-09-13 48 views
2

我正在尋找一種方法來連接一個結果和一個字符串,其結果是一個平靜。其實,如果我使用paste0()quo_name(),我可以做到。但我想知道是否有更優雅的替代方案在我的包中編寫函數。這是一個普通的例子:concatenate quosures和字符串

library(dplyr) 

df <- data_frame(
    z_1 = 1, 
    z_2 = 2, 
    y_1 = 10, 
    y_2 = 20 
) 

get_var <- function(.data, var) { 
    xx = enquo(var) 

    select(.data, paste0(quo_name(xx), "_1"), paste0(quo_name(xx), "_2")) 
} 

get_var(df, z) 
# A tibble: 1 x 2 
    z_1 z_2 
    <dbl> <dbl> 
1  1  2 

回答

2

沒有的功能,這是它使用dplyr你怎麼做:

library(dplyr) 
df %>% 
    select(starts_with("z_")) 

您還可以創建一個功能,在傳遞一個字符串像這樣的變量名:

get_var= function(df, var){ 
    df %>% 
    select(starts_with(paste0(var, "_"))) 
} 

get_var(df, "z") 

現在,棘手部分,當你試圖在變量名通過不引用它變成一個功能(將R代碼,而不是它包含的值)。這樣做的一個辦法是在基地R. deparse + substitute這種轉換提供給var爲一個字符串,這是便於在函數中以後使用符號

get_var = function(df, var){ 
    var_quo = deparse(substitute(var)) 
    df %>% 
    select(starts_with(paste0(var_quo, "_"))) 
} 

最後,這裏是如何做enquoquo_name同在rlang/tidyverse包:

library(rlang) 
get_var = function(df, var){ 
    var_quo = quo_name(enquo(var)) 
    df %>% 
    select(starts_with(paste0(var_quo, "_"))) 
} 

get_var(df, z) 
get_var(df, y) 

結果:

# A tibble: 1 x 2 
    z_1 z_2 
    <dbl> <dbl> 
1  1  2 

# A tibble: 1 × 2 
    y_1 y_2 
    <dbl> <dbl> 
1 10 20 

注:

  1. quosures被引述跟蹤的環境表現。
  2. enquo採用引用函數參數的符號,引用R代碼並將其與函數的環境在一個平靜中捆綁在一起。
  3. quo_name將一個定理格式化爲一個字符串,該字符串可以在函數中稍後使用。
  4. quo_textquo_name類似,但不檢查輸入是否是符號。

檢查這些:

  1. rlang documentation
  2. Non-Standard Evaluation in R
  3. ?enquo
  4. ?quo_name
+0

如果你可以通過一個變量名到你的選擇,我會給予好評。 'starts_with'是我使用的方法 – CPak

+0

@我知道。所以你希望能夠傳遞變量本身,而不是像「z」那樣的字符串?例如,'get_var(df,「z」)'不會令人滿意嗎? – useR

+1

我不是OP順便說一句。基本上,OP想要定義一個函數,其中數據框和列到選擇是作爲參數動態傳遞的。 – CPak