r - 知道在连接之前使用哪个data.table连接

时间:2016-03-08 09:45:42

标签: r data.table

问题

是否可以知道哪个是效率最高的data.table'加入'在执行加入之前使用?

这样做的目的是在公共密钥dt1上加入两个表dt2alpha,其中dt1$beta <= dt2$beta。两个示例表:

# dt1                       dt2
#        id alpha beta          alpha beta
#  1:    35   A   284       1:      A  478
#  2:    74   A   916       2:      A 1034
#  ---                      --- 
# 9999:  9967 Z   483       9999:   Z  303
# 10000: 9988 Z   473       10000:  Z 1411

可能是non-equi加入,实施时会解决这个问题,但是现在我想知道是否有办法从两个表的大小告诉最好的方法使用

在示例中,最快的&#39;方法根据表的大小而变化。它们也代表了我的实际数据,这些数据会定期更改,因此我希望编写一个使用“最佳”数据的函数。加入。

实施例

在这里,我设置了一些功能来创建数据,执行几个连接并运行基准测试。基准测试在三个不同大小的表上运行

library(data.table)
library(microbenchmark)

## Function to create data.tables
fun_create_data <- function(s1, s2){
  set.seed(123)   ## keep consistency
  dt1 <- data.table(id = seq(1:s1),
                    alpha = sample(LETTERS, size=s1, replace=T),
                    beta = sample(1:1440, size=s1, replace=T))

  dt2 <- data.table(alpha = sample(LETTERS, size=s2, replace=T),
                    beta = sample(1:1440, size=s2, replace=T))

  setkey(dt1, alpha)
  setkey(dt2, alpha)

  return(lst = list(dt1, dt2))
}

我使用的联接是

## inner join, allow.cartesian = TRUE,
## then filtering out results after the join
fun_join_cartesian <- function(dt1, dt2){

  dt1[ dt2, nomatch=0, allow.cartesian=TRUE][beta <= i.beta]

}

## join using i.col (specifying criteria for each i.)
fun_join_eachi <- function(dt1, dt2){

  dt1[ dt2, {
              idx = beta <= i.beta
              .(id = id[idx],
               beta = beta[idx],
              i.beta = i.beta)
            },
            by=.EACHI
      ][!is.na(id)]

}

基准功能

fun_mb <- function(dt1, dt2){
  microbenchmark(
    fun_join_cartesian(dt1, dt2),
    fun_join_eachi(dt1, dt2),
    times=10
  )
}

fisrt示例使笛卡尔联接表现最佳

s1 <- 1000
s2 <- s1 
lst <- fun_create_data(s1, s2)
dt1 <- lst[[1]]
dt2 <- lst[[2]]

fun_mb(dt1, dt2)
# Unit: milliseconds
#                         expr      min       lq     mean   median       uq      max neval
# fun_join_cartesian(dt1, dt2) 1.727606 1.741692 1.785893 1.770675 1.778107 1.986325    10
#     fun_join_eachi(dt1, dt2) 3.490216 3.518185 3.593305 3.559949 3.662209 3.826939    10

第二个例子也有笛卡尔连接表现最佳

s1 <- 1000
s2 <- s1 * 5
lst <- fun_create_data(s1, s2)
dt1 <- lst[[1]]
dt2 <- lst[[2]]

fun_mb(dt1, dt2)
# Unit: milliseconds
#                         expr       min       lq      mean    median       uq      max neval
# fun_join_cartesian(dt1, dt2)  5.690791  5.70429  6.433174  5.923583  6.19849 10.84091    10
#     fun_join_eachi(dt1, dt2) 12.153050 12.47688 13.469481 12.711631 13.46108 18.71149    10

而第三个示例的eachi联接表现最佳

s1 <- 10000
s2 <- s1
lst <- fun_create_data(s1, s2)
dt1 <- lst[[1]]
dt2 <- lst[[2]]

fun_mb(dt1, dt2)
# Unit: milliseconds
#                         expr       min        lq     mean   median       uq      max neval
# fun_join_cartesian(dt1, dt2) 170.16523 171.33960 185.9685 173.3784 175.3022 299.5541    10
#     fun_join_eachi(dt1, dt2)  88.17374  95.48863 138.8535 155.7180 161.2675 162.1637    10

0 个答案:

没有答案