Skip to content

Commit

Permalink
Closes Rdatatable#1257, on=.() syntax is now possible.
Browse files Browse the repository at this point in the history
  • Loading branch information
arunsrinivasan authored and tangjian.li committed Aug 13, 2017
1 parent 3e1c5a8 commit 5cceea5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
19 changes: 15 additions & 4 deletions R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -597,11 +597,22 @@ chmatch2 <- function(x, table, nomatch=NA_integer_) {
stop("When i is a data.table (or character vector), the columns to join by must be specified either using 'on=' argument (see ?data.table) or by keying x (i.e. sorted, and, marked as sorted, see ?setkey). Keyed joins might have further speed benefits on very large data due to x being sorted in RAM.")
}
if (!missing(on)) {
if (!is.character(on))
stop("'on' argument should be a named atomic vector of column names indicating which columns in 'i' should be joined with which columns in 'x'.")
parse_on <- function(on) {
# on = .() is now possible, #1257
parse_on <- function(onsub) {
ops = c("==", "<=", "<", ">=", ">", "!=")
pat = paste("(", ops, ")", sep = "", collapse = "|")
if (is.call(onsub) && onsub[[1L]] == "eval") {
onsub = eval(onsub[[2L]], parent.frame(2L), parent.frame(2L))
if (is.call(onsub) && onsub[[1L]] == "eval") onsub = onsub[[2L]]
}
if (is.call(onsub) && as.character(onsub[[1L]]) %in% c("list", ".")) {
spat = paste("[ ]+(", pat, ")[ ]+", sep="")
onsub = lapply(as.list(onsub)[-1L], function(x) gsub(spat, "\\1", deparse(x, width.cutoff=500L)))
onsub = as.call(c(quote(c), onsub))
}
on = eval(onsub, parent.frame(2L), parent.frame(2L))
if (!is.character(on))
stop("'on' argument should be a named atomic vector of column names indicating which columns in 'i' should be joined with which columns in 'x'.")
this_op = regmatches(on, gregexpr(pat, on))
idx = (vapply(this_op, length, 0L) == 0L)
this_op[idx] = "=="
Expand All @@ -620,7 +631,7 @@ chmatch2 <- function(x, table, nomatch=NA_integer_) {
names(on)[empty_idx] = on[empty_idx]
list(on = on, ops = idx_op)
}
on_ops = parse_on(on)
on_ops = parse_on(substitute(on))
on = on_ops[[1L]]
ops = on_ops[[2L]]
# TODO: collect all '==' ops first to speeden up Cnestedid
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@

30. x's columns can be referred to in `j` using the prefix `x.` at all times. This is particularly useful when it is necessary to x's column that is *also a join column*. This is a patch addressing [#1615](https://github.com/Rdatatable/data.table/issues/1615).

31. `on=.()` syntax is now posible, e.g., `X[Y, on=.(x==a, y==b)]`, [#1257](https://github.com/Rdatatable/data.table/issues/1257). Thanks @dselivanov.

#### BUG FIXES

1. Now compiles and runs on IBM AIX gcc. Thanks to Vinh Nguyen for investigation and testing, [#1351](https://github.com/Rdatatable/data.table/issues/1351).
Expand Down
9 changes: 9 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -8651,6 +8651,15 @@ dt1 = data.table(x=sample(letters[1:2], 10, TRUE), y=sample(c(1L,5L,7L), 10, TRU
dt2 = data.table(x=c("b", "a"), y=c(1L, 9L))
test(1654, dt1[dt2, on="x>x"], error="Only '==' operator")

# on= with .() syntax, #1257
dt1 = data.table(x=sample(letters[1:2], 10, TRUE), y=sample(c(1L,5L,7L), 10, TRUE), z=1:10, k=11:20)
dt2 = data.table(x=c("b", "a"), y=c(1L, 9L))
test(1655.1, dt1[dt2, on=.(x)], dt1[dt2, on="x"])
test(1655.2, dt1[dt2, on=.(x==x)], dt1[dt2, on=c("x==x")])
test(1655.3, dt1[dt2, on=.(x==x)], dt1[dt2, on=c("x"="x")])
test(1655.4, dt1[dt2, on=.(y>=y)], dt1[dt2, on=c("y>=y")])
test(1655.4, dt1[dt2, on=.(x==x, y>=y)], dt1[dt2, on=c("x==x", "y>=y")])

##########################

# TODO: Tests involving GForce functions needs to be run with optimisation level 1 and 2, so that both functions are tested all the time.
Expand Down

0 comments on commit 5cceea5

Please sign in to comment.