以表达式作为 dplyr 摘要参数的 R 函数
R function with expression as parameter for dplyr summarise
好吧,这件事感觉应该是相对容易的,但尽管我已经尝试了几十种方法 quote
、eval
、substitute
、enquote
、parse
、summarize_
等...我还没有让它工作。基本上我正在尝试计算这样的东西 - 但是 summarise
参数有一个变量表达式:
mtcars %>% group_by(cyl) %>% summarise(wt=mean(wt),hp=mean(hp))
产量:
# A tibble: 3 × 3
cyl wt hp
<dbl> <dbl> <dbl>
1 4 2.285727 82.63636
2 6 3.117143 122.28571
3 8 3.999214 209.21429
我尝试过的其中一件事是:
x2 <- "wt=mean(wt),hp=mean(hp)"
mtcars %>% group_by(cyl) %>% summarise(eval(parse(text=x2)))
产量:
Error in eval(substitute(expr), envir, enclos) :
<text>:1:12: unexpected ','
1: wt=mean(wt),
但是如果不考虑第二个参数 (",hp=mean(hp"
),您将无法继续前进:
> x2 <- "wt=mean(wt)"
> mtcars %>% group_by(cyl) %>% summarise(eval(parse(text=x2)))
Error in eval(substitute(expr), envir, enclos) : object 'wt' not found
我会为你省去我尝试过的所有其他事情——我显然遗漏了一些关于如何在函数参数中处理表达式的内容。
那么这里的正确方法是什么?记住我最后真的想要这样的东西:
getdf <- function(df,sumarg){
df %>% group_by(cyl) %>% summarise(sumarg)
df
}
也不确定我应该为 R 世界中的这种查询使用哪种标签。元编程?
为了获得最大的灵活性,我会使用 ...
参数,使用 lazyeval
捕获这些点,然后传递给 summarise_
:
getdf <- function(df, ...){
df %>% group_by(cyl) %>% summarise_(.dots = lazyeval::lazy_dots(...))
}
那你可以直接做:
getdf(mtcars, wt = mean(wt), hp = mean(hp))
# A tibble: 3 × 3
cyl wt hp
<dbl> <dbl> <dbl>
1 4 2.285727 82.63636
2 6 3.117143 122.28571
3 8 3.999214 209.21429
不使用 ...
的一种方法是在列表中传递参数,尽管您需要使用公式或引号。例如:
getdf2 <- function(df, args){
dots <- lazyeval::as.lazy_dots(args)
df %>% group_by(cyl) %>% summarise_(.dots = dots)
}
并用作:
getdf(mtcars, list(wt = ~mean(wt), hp = ~mean(hp)))
或
getdf(mtcars, list(wt = "mean(wt)", hp = "mean(hp)"))
好吧,这件事感觉应该是相对容易的,但尽管我已经尝试了几十种方法 quote
、eval
、substitute
、enquote
、parse
、summarize_
等...我还没有让它工作。基本上我正在尝试计算这样的东西 - 但是 summarise
参数有一个变量表达式:
mtcars %>% group_by(cyl) %>% summarise(wt=mean(wt),hp=mean(hp))
产量:
# A tibble: 3 × 3
cyl wt hp
<dbl> <dbl> <dbl>
1 4 2.285727 82.63636
2 6 3.117143 122.28571
3 8 3.999214 209.21429
我尝试过的其中一件事是:
x2 <- "wt=mean(wt),hp=mean(hp)"
mtcars %>% group_by(cyl) %>% summarise(eval(parse(text=x2)))
产量:
Error in eval(substitute(expr), envir, enclos) :
<text>:1:12: unexpected ','
1: wt=mean(wt),
但是如果不考虑第二个参数 (",hp=mean(hp"
),您将无法继续前进:
> x2 <- "wt=mean(wt)"
> mtcars %>% group_by(cyl) %>% summarise(eval(parse(text=x2)))
Error in eval(substitute(expr), envir, enclos) : object 'wt' not found
我会为你省去我尝试过的所有其他事情——我显然遗漏了一些关于如何在函数参数中处理表达式的内容。
那么这里的正确方法是什么?记住我最后真的想要这样的东西:
getdf <- function(df,sumarg){
df %>% group_by(cyl) %>% summarise(sumarg)
df
}
也不确定我应该为 R 世界中的这种查询使用哪种标签。元编程?
为了获得最大的灵活性,我会使用 ...
参数,使用 lazyeval
捕获这些点,然后传递给 summarise_
:
getdf <- function(df, ...){
df %>% group_by(cyl) %>% summarise_(.dots = lazyeval::lazy_dots(...))
}
那你可以直接做:
getdf(mtcars, wt = mean(wt), hp = mean(hp))
# A tibble: 3 × 3 cyl wt hp <dbl> <dbl> <dbl> 1 4 2.285727 82.63636 2 6 3.117143 122.28571 3 8 3.999214 209.21429
不使用 ...
的一种方法是在列表中传递参数,尽管您需要使用公式或引号。例如:
getdf2 <- function(df, args){
dots <- lazyeval::as.lazy_dots(args)
df %>% group_by(cyl) %>% summarise_(.dots = dots)
}
并用作:
getdf(mtcars, list(wt = ~mean(wt), hp = ~mean(hp)))
或
getdf(mtcars, list(wt = "mean(wt)", hp = "mean(hp)"))