如何在data.table函数中传递省略号(...)实现多列左连接?
解决data.table自定义函数中传递多列连接条件的问题
问题根源
直接在函数里写on = .(...)时,...不会被展开为传入的列映射关系,而是被当作一个字面量列名,导致data.table寻找名为...的列,自然触发不存在列的错误。
正确实现方式
有两种常用方法可以正确传递多列连接条件:
方法1:用substitute捕获连接条件并求值
library(data.table) # 示例数据集 df <- data.table(mnd = c("2023-01", "2023-02"), c = c(1, 2), value1 = c(10, 20)) dat <- data.table(date = c("2023-01", "2023-02"), id = c(1, 2), value2 = c(100, 200)) # 自定义连接函数 dtable_func <- function(x, y, ...) { # 捕获传入的连接条件表达式 on_expr <- substitute(list(...)) # 在data.table调用环境中求值表达式 x[y, on = eval(on_expr), nomatch = NULL] } # 调用测试 dtable_func(df, dat, mnd = date, c = id)
方法2:将连接条件转为列表传递
dtable_func <- function(x, y, ...) { # 提取传入的键值对为列表 on_list <- as.list(substitute(list(...)))[-1] # 直接将列表传给on参数 x[y, on = on_list, nomatch = NULL] } # 调用测试 dtable_func(df, dat, mnd = date, c = id)
输出结果
两种方法都会返回正确的左连接结果:
mnd c value1 value2 1: 2023-01 1 10 100 2: 2023-02 2 20 200
原理说明
substitute(list(...))会捕获你传入的mnd = date, c = id这类原始表达式,而非直接展开...- 方法1通过
eval在data.table的调用上下文执行表达式,生成正确连接条件;方法2直接将表达式转为列表,而data.table的on参数本身支持这种列映射格式的列表。
内容的提问来源于stack exchange,提问作者Matthew Cassell
相关产品推荐
相关产品推荐

