2017-12-27 236 views
0

我想創建一個函數,將列名稱列表傳遞給dplyr函數。我知道,如果列名稱的列表中...形式給出如何做到這一點,作爲tidyeval文檔中解釋說:Tidyeval與功能列名稱列表

df <- tibble(
    g1 = c(1, 1, 2, 2, 2), 
    g2 = c(1, 2, 1, 2, 1), 
    a = sample(5), 
    b = sample(5) 
) 

my_summarise <- function(df, ...) { 
    group_var <- quos(...) 

    df %>% 
    group_by(!!!group_var) %>% 
    summarise(a = mean(a)) 
} 

my_summarise(df, g1, g2) 

但如果我要列出列名作爲函數的參數時,上述解決方案(當然)將無法正常工作:

my_summarise <- function(df, group_var, sum_var) { 
    group_var <- quos(group_var) # nor enquo(group_var) 
    sum_var <- enquo(sum_var) 

    df %>% 
    group_by(!!!group_var) %>% 
    summarise(a = mean(a)) 
} 

my_summarise(df, list(g1, g2), a) 
my_summarise(df, list(g1, g2), b) 

我怎樣才能在列表裏面的物品進行單獨報價?

這個問題類似於Passing dataframe column names in a function inside another function,但在評論中建議使用字符串,而在這裏我想使用裸列名。

+0

也許這裏是與您的問題相關的另一個問題https://stackoverflow.com/questions/44166247/referring-to-individual-variables-in-with-dplyr-quos –

+1

如何將您的「group_var」參數作爲通過'quos'而不是'list',如[回答]的第一部分所示(https://stackoverflow.com/a/44593617/2461552)? – aosmith

回答

0

您可以使用alist而不是list來傳遞參數列表,因爲它不會評估參數。

my_summarise = function(df, group_var, sum_var) { 
    group_var = quos(!!! group_var) 
    sum_var = enquo(sum_var) 

    df %>% 
     group_by(!!! group_var) %>% 
     summarise(!! quo_name(sum_var) := mean(!! sum_var)) 
} 

my_summarise(df, alist(g1, g2), b) 

# A tibble: 4 x 3 
# Groups: g1 [?] 
    g1 g2  b 
    <dbl> <dbl> <dbl> 
1  1  1 2.0 
2  1  2 3.0 
3  2  1 4.5 
4  2  2 1.0 

另一種方法是直接與quos代替list通過這樣的說法,如圖in this answer,它繞過一些併發症都在一起。

my_summarise = function(df, group_var, sum_var) { 
    # group_var = quos(!!! group_var) 
    sum_var = enquo(sum_var) 

    df %>% 
     group_by(!!! group_var) %>% 
     summarise(!! quo_name(sum_var) := mean(!! sum_var)) 
} 

my_summarise(df, quos(g1, g2), b) 

# A tibble: 4 x 3 
# Groups: g1 [?] 
    g1 g2  b 
    <dbl> <dbl> <dbl> 
1  1  1 2.0 
2  1  2 3.0 
3  2  1 4.5 
4  2  2 1.0 
1
library(dplyr) 

df <- tibble(
    g1 = c(1, 1, 2, 2, 2), 
    g2 = c(1, 2, 1, 2, 1), 
    a = sample(5), 
    b = sample(5) 
) 

my_summarise = function(df, group_var, fun_name) { 

    df %>% 
    group_by(!!! group_var) %>% 
    summarize_all(fun_name) 
} 

my_summarise(df, alist(g1, g2), mean) 

ALIST()處理參數 'G1' 和 'G2' 作爲函數的參數(不對其進行評估),而!!! (與UQS()相同)引用和拼接列表sum_var並不是必須的,因爲它看起來像是想要採用'a'和'b'的意思,還可以通過傳遞函數來概括它。

+1

這是正確的答案。您希望引用()::'rlang :: exprs()'或者'dplyr :: vars ()'。 – lionel