1

我在函数中混合 SE 和 NSE dplyr 评估时遇到了困难。我有一个数据集,我想根据不同列上的出现次数来划分每一列。

让我用我所追求的功能写一个小函数

func <- function(param) {
 mtcars %>%
 group_by(cyl) %>%
 summarise_each(funs_(lazyeval::interp(~sum(.))/lazyeval::interp(~sum(var == 
 0), var = as.name(param))))
 }

函数将被使用,例如func(am)func(vs)

我已经尝试了该功能的各种替代方案,但没有一个有效。

我错过了什么?

4

1 回答 1

2

在这种情况下,它funs需要在其标准评估版本 ( funs_) 中使用。此外,整个公式都在一次调用interp. 例如:

func <- function(param, data=mtcars) {
  data %>%
    group_by(cyl) %>%
    summarise_each(funs_(lazyeval::interp(~sum(.)/sum(.[var==0]), var = as.name(param))))
}

func("vs")
    cyl      mpg     disp       hp      drat        wt      qsec    vs    am  gear  carb
1     4 11.28077 9.613466 9.989011 10.108352 11.749065 12.605389   Inf   Inf   Inf   Inf
2     6  2.23987 2.759570 2.167089  2.197898  2.640048  2.569212   Inf   Inf   Inf   Inf
3     8  1.00000 1.000000 1.000000  1.000000  1.000000  1.000000   NaN    NA    NA    NA

或者,更一般的功能:

func <- function(param, param.subset, groupvar, data) {
  data %>%
    group_by_(groupvar) %>%
    summarise_each(funs_(lazyeval::interp(
      ~if(is.numeric(.)) {
        sum(.[var==param.subset])/sum(.)
      } else {
        length(unique(.[var==param.subset]))
      }, var = as.name(param))))
}

func(param="gender", param.subset="Girl", groupvar="grade", data=vcd::JointSports)
   grade      Freq opinion  year gender
1    1st 0.5866477       5     2      1
2    3rd 0.6137566       5     2      1

我仍然觉得我并没有真正“获得” dplyr 的标准评估,并且会对是否有比上面的代码更好的方法感兴趣。

于 2017-03-01T22:08:18.040 回答