如何在数据表中定义键控(分组)连接?

时间:2018-04-04 21:04:33

标签: r data.table

我想重载[.data.table运算符,以便可以实现分组连接。我将使用dplyr来说明分组连接的含义。例如,下面的函数包裹dplyr::inner_join

inner_join_grp <- function(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), 
                           ...) {
    stopifnot(identical(group_vars(x), group_vars(y)))


    grp <- group_vars(x)

    by <- c(by, grp)

    return(inner_join(x, y, by, copy, suffix, ...))
}

所有这个函数都是检查输入data.frames xy是否具有相同的组,如果是,则将分组变量添加到{{1}指定的连接键中}}

应用程序将是这样的:

by = ...

使用我的功能:

n_grp <- 5
n_grp2 <- 3

set.seed(0)

tmp_df <-
    data.frame(grp = rep(letters[1:n_grp2], each = n_grp),
               grp2 = rep(1:n_grp, times = n_grp2),
               x = runif(n_grp * n_grp2))

tmp_df_2 <-
    data.frame(grp = rep(letters[1:n_grp2], each = n_grp),
               grp2 = rep(1:n_grp, times = n_grp2),
               y = runif(n_grp * n_grp2))

生成预期的十五行表:

tmp_df %>%
    group_by(grp) %>%
    inner_join_grp(tmp_df_2 %>% 
                   group_by(grp), 
               by = "grp2")

而使用# A tibble: 15 x 4 # Groups: grp [?] grp grp2 x y <fct> <int> <dbl> <dbl> 1 a 1 0.897 0.770 2 a 2 0.266 0.498 3 a 3 0.372 0.718 4 a 4 0.573 0.992 5 a 5 0.908 0.380 ... 生成45行表,因为联接只在dplyr::inner_join上:

grp2

我的问题是,当输入数据表被键控时,是否可以使用# A tibble: 45 x 5 # Groups: grp.x [?] grp.x grp2 x grp.y y <fct> <int> <dbl> <fct> <dbl> 1 a 1 0.897 a 0.770 2 a 1 0.897 b 0.777 3 a 1 0.897 c 0.267 ... 实现类似的功能。我知道我可以以相同的方式重载[(参见下面的粗略示例),但我更愿意将另一个参数传递给merge.data.table以实现键控连接。

[

1 个答案:

答案 0 :(得分:2)

这些方面应该有效:

`[.data.table` = function(x, i, ...) {
  args = match.call()
  if ('on' %in% names(args)) {
    args[['on']] = union(args[['on']], intersect(key(x), key(i)))
  }
  args[[1]] = data.table:::`[.data.table`
  eval(args)
}