Объединить конвейерные функции в блоки кода - PullRequest
0 голосов
/ 17 мая 2018

Я хотел бы обобщить конвейерные функции (из magrittr / dplyr) в более короткие функциональные «блоки» (чтобы, надеюсь, иметь более читаемый код). Например:

library(dplyr)

d <- tbl_df(data.frame(A = rep(LETTERS[2:5], each = 5),
                       M = rep(letters[1:2], times = 10),
                       X = round(rnorm(20, 10, 2), 1)))

# I want to replace this
# ----------------------
d %>%
  group_by(A) %>%
  summarise(X = mean(X)) -> d_test_1

# with this
# ---------
my_mean <- function(d, by_var, x) {
  expr <- substitute(by_var) # group variable, seems ok
  expr_2 <- substitute(expression(x = mean(x))) # calculate mean
  print(deparse(expr_2))
  # problem: x = mean(x) is only substituted to x = mean(X) .. 1 capital x, should be 2
  expr_3 <- parse(text = paste(deparse(substitute(x)), "=mean(", 
                               deparse(substitute(x)), ")"))
  print(deparse(expr_3))
  # expr_3 does not work either
  d %>%
    group_by(eval(expr)) %>%
    #summarise(X = mean(X)) -> d # uses right group variable
    summarise(eval(expr_3)) -> d # uses wrong group variable <> side-effect of "expr"?
  invisible(d)
}

# this is the short version I am after
d %>%
  my_mean(A, X) -> d_test_2
d_test_1
d_test_2

Спасибо и с уважением

1 Ответ

0 голосов
/ 18 мая 2018

Может быть, кто-то еще не знает, где искать:

library(dplyr)

d <- tbl_df(data.frame(A = rep(LETTERS[2:5], each = 5),
                       M = rep(letters[1:2], times = 10),
                       X = round(rnorm(20, 10, 2), 1),
                       stringsAsFactors = F))

my_mean <- function(d, by_var, x) {
  d %>%
    group_by(!!enquo(by_var)) %>%
    summarise(!!quo_name(enquo(x)) := mean(!!enquo(x))) 
}

d %>%
  my_mean(A, X) -> want
want
...