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使用自定义函数及Reduce函数实现一次性性多表连接