r data.table 围绕 ad-hoc 连接的函数包装器(在链中聚合)

Posted

技术标签:

【中文标题】r data.table 围绕 ad-hoc 连接的函数包装器(在链中聚合)【英文标题】:r data.table function wrapper around ad-hoc join (with aggregation in a chain) 【发布时间】:2016-06-08 15:08:41 【问题描述】:

[data.table_1.9.6] 问题的背景是我正在尝试在类似星型模式的数据布局中构建类似 olap 的查询功能,即一个大型事实表和几个元表。我正在围绕 data.table 连接构建一个函数包装器,然后是链中的聚合:

# dummy data
dt1 = data.table(id = 1:5, x=letters[1:5], a=11:15, b=21:25)
dt2 = data.table(k=11:15, z=letters[11:15])

# standard data.table query with ad-hoc key -> works fine
dt1[dt2, c("z") := .(i.z), with = F, 
    on = c(a="k")][, .(m = sum(a, na.rm = T),
                   count = .N), by = c("z")]

# wrapper function with setkey -> works fine
agg_foo <- function(x, meta_tbl, x_key, meta_key, agg_var)  
  setkeyv(x, x_key)
  setkeyv(meta_tbl, meta_key)
  x[meta_tbl, (agg_var) := get(agg_var)][,.(a_sum = sum(a, na.rm=T),
                                            count = .N), 
                                         by = c(agg_var)]
  x[, (agg_var) := .(NULL)]
  

# call function (works fine)
agg_foo(x=dt1, meta_tbl=dt2, x_key="a", meta_key="k",agg_var="z")

# wrapper function with ad-hoc key -> does not work
agg_foo_ad_hoc <- function(x, meta_tbl, x_key, meta_key, agg_var)  
  x[meta_tbl, (agg_var) := get(agg_var), 
    on = c(x_key = meta_key)][,.(a_sum = sum(a, na.rm=T),
                                 count = .N), by = c(agg_var)]
  x[, (agg_var) := .(NULL)]
  

# call function (causes error)
agg_foo_ad_hoc(x=dt1, meta_tbl=dt2, x_key="a", meta_key="k",agg_var="z")

Error in forderv(x, by = rightcols) : 
  'by' value -2147483648 out of range [1,4]

我的猜测是我必须以不同的方式提供临时“on”参数。我试过 = c(get(x_key) = meta_key) 但后来他抱怨意外的括号。我可以使用该函数的 setkey 版本,但我想知道这是否有效,因为该函数将根据使用的聚合属性在不同的元表上工作,从而不断重新设置密钥。还是 setkey 总是首选?实际的事实表(此处为 x)有 > 3000 万行。

【问题讨论】:

您可能需要检查 data.cube 包,该包根据 data.tables 集定义了 OLAP 多维数据集 R 数据类型。包中有cube 类,它是星型模式建模的。在开发分支 data.cube-oop 中有一个新的data.cube 类,它是星型和雪花模式的混合,在this SO question 中进行了描述。它会自动对可用维度进行子聚合,并保持多维数据集中的数据标准化。 @jangorecki:我知道你的包裹。过去已经调查过了。无论如何,谢谢你的提示!如果它没有被企业 IT 阻止,我也很乐意浏览它的 github 源。但是是否有仅 data.table 的实现? 实际的上游仓库在gitlab.com/jangorecki/data.cube,所以你可以在那里尝试。实现基于data.table 和big.data.table 用于事实表(到目前为止仅部分用于cube 类)。后者允许将事实表分布在多台机器上,消除内存限制并允许并行查询,能够有效地处理 OLAP 大数据。 【参考方案1】:

您需要做的就是构造一个带有正确标签的向量。这是这样做的一种方法:

agg_foo_ad_hoc <- function(x, meta_tbl, x_key, meta_key, agg_var)  
  x[meta_tbl, (agg_var) := get(agg_var), 
    on = setNames(meta_key, x_key)][,.(a_sum = sum(a, na.rm=T),
                                       count = .N), by = c(agg_var)]
  x[, (agg_var) := .(NULL)]

【讨论】:

您对功能设计有意见吗,即 setkey 是否优于 ad-hoc key? @Triam 现在我几乎只使用on。它更灵活,而且我喜欢知道我在每个操作中正在做什么,而不是在代码的其他部分使用setkey 然后必须记住我已经这样做了。我现在使用setkey 的唯一情况是,如果我需要在同一个键上连续执行多个连接/查找。

以上是关于r data.table 围绕 ad-hoc 连接的函数包装器(在链中聚合)的主要内容,如果未能解决你的问题,请参考以下文章

R语言data.table进行滚动数据连接,滚动联接通常用于分析涉及时间的数据实战(动画说明滚动数据连接的形式):rolling joins data.table in R

滚动连接R中的data.table

在data.table R中滚动连接

R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表连接

将外键上的 SQL 连接转换为 R data.table 语法

R data.table 合并/完全外连接与 na.fill / nomatch 基于公式