使用 data.table join 将表达式作为参数提供给函数

Supply expression as argument to function using data.table join

我希望能够使用包含表达式的字符串作为与 data.table 连接的函数的参数。见下文;

> library(data.table)
> 
> x <- data.table(Id  = c("A", "B", "C", "C"),
+                 X1  = c(1L, 3L, 5L, 7L),
+                 X2 = c(8L,12L,9L,18L),
+                 XY  = c("x2", "x4", "x6", "x8"))
> 
> z <- data.table(ID = "C", Z1 = 5:9, Z2 = paste0("z", 5:9))
> 
> 
> x[z, on = .(Id == ID), mult = "all", allow.cartesian=TRUE]
    Id X1 X2 XY Z1 Z2
 1:  C  5  9 x6  5 z5
 2:  C  7 18 x8  5 z5
 3:  C  5  9 x6  6 z6
 4:  C  7 18 x8  6 z6
 5:  C  5  9 x6  7 z7
 6:  C  7 18 x8  7 z7
 7:  C  5  9 x6  8 z8
 8:  C  7 18 x8  8 z8
 9:  C  5  9 x6  9 z9
10:  C  7 18 x8  9 z9
> 
> # Conversion to a function. Need to work out the piece - evaluate_string_to_correct_format
> data_table_join <- function(x,y,string){
+     
+     x[y, on = evaluate_string_to_correct_format(string),
+       mult = "all", allow.cartesian = TRUE]
+     
+ }

这里的字符串应该等于“.(Id == ID)” 我只是不确定如何到达它工作的地步。我希望能够用字符串替换 data.table 调用的多个部分,所以这只是一个最小的示例。

参数 on 可以采用字符向量作为输入,而不仅仅是表达式。所以你可以只提供 on="Id==ID"。对于多个条件,使用长度为 2+ 的字符向量,如 c("a==b","x==y")。您还应该在 ?data.table 手册中找到有用的示例。

x[z, on = "Id==ID", mult = "all", allow.cartesian=TRUE]

x[z, on = c("Id==ID", "X1==Z1"), mult = "all", allow.cartesian=TRUE]

如果您不想使用字符串而是表达式,那么您需要 substitute 在您的函数中使用它。

data_table_join <- function(x,y,expr) {
  eval(substitute(
    x[y, on = .expr,
      mult = "all", allow.cartesian = TRUE]
    list(.expr = expr)
  ))
}

这就是 NSE 在 R 中的工作方式,请阅读基础 R ?substitute 手册或 R 语言手册中的语言计算部分:https://cran.r-project.org/doc/manuals/R-lang.html#Computing-on-the-language

至于参数化 data.table 查询的其他部分,您可能会发现此 Q 很有用:How can one work fully generically in data.table in R with column names in variables