Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ unit = "s")

5. `frank(..., ties.method="random", na.last=NA)` now returns the same random ordering that `base::rank` does, [#4243](https://github.com/Rdatatable/data.table/pull/4243).

6. The error message when mistakenly using `:=` in `i` instead of `j` has been much improved, [#4227](https://github.com/Rdatatable/data.table/issues/4227). Thanks to Hugh Parsonage for the detailed suggestion.

```R
> DT = data.table(A=1:2)
> DT[B:=3]
Error: Operator := detected in i, the first argument inside DT[...], but is only valid in the second argument, j. Most often, this happens when forgetting the first comma (e.g. DT[newvar := 5] instead of DT[ , new_var := 5]). Please double-check the syntax. Run traceback(), and debugger() to get a line number.
> DT[,B:=3]
> DT
A B
<int> <num>
1: 1 3
2: 2 3
```


# data.table [v1.12.8](https://github.com/Rdatatable/data.table/milestone/15?closed=1) (09 Dec 2019)

Expand Down
14 changes: 13 additions & 1 deletion R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -2611,7 +2611,19 @@ vecseq = function(x,y,clamp) .Call(Cvecseq,x,y,clamp)
# .Call(Caddress, x) increments NAM() when x is vector with NAM(1). Referring object within non-primitive function is enough to increment reference.
address = function(x) .Call(Caddress, eval(substitute(x), parent.frame()))

":=" = function(...) stop('Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").')
":=" = function(...) {
# detect common mistake -- using := in i due to forgetting a comma to leave it blank, #4227
find_doteq_in_i = function(e) {
if (is.call(e)) {
if (is.symbol(e[[1L]]) && e[[1L]] == '[.data.table' && is.call(e[[3L]]) && is.symbol(e[[3L]][[1L]]) && e[[3L]][[1L]] == ':=') {
stop("Operator := detected in i, the first argument inside DT[...], but is only valid in the second argument, j. Most often, this happens when forgetting the first comma (e.g. DT[newvar := 5] instead of DT[ , new_var := 5]). Please double-check the syntax. Run traceback(), and debugger() to get a line number.")
}
else lapply(e[-1L], find_doteq_in_i)
}
}
for (calli in sys.calls()) find_doteq_in_i(calli)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a bad feeling about using sys.calls here. I would rather check for := when massaging isub argument

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this will cover 95% of cases :)

stop('Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").')
}

setDF = function(x, rownames=NULL) {
if (!is.list(x)) stop("setDF only accepts data.table, data.frame or list of equal length as input")
Expand Down
9 changes: 5 additions & 4 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -16792,7 +16792,8 @@ if (test_xts) {
test(2133.5, as.data.table(xts, keep.rownames = NA_character_),
error = "keep.rownames must not be NA")
}

########################
# Add new tests here #
########################

# friendlier error for common mistake of using := in i instead of j, #4227
DT = data.table(a = 1)
test(2134.1, DT[b := 2], error="Operator := detected in i, the first argument inside DT[...], but is only valid in the second argument, j.")
test(2134.2, DT[DT[mpg_per_cl := mpg/cyl], on='ast'], error="Operator := detected in i, the first argument inside")