Skip to content

Commit 878baf7

Browse files
Exclude '..1' from up-a-level search
1 parent 1e2e3ba commit 878baf7

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

NEWS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@
8181
18. Fixed incorrect sorting of merges where the first column of a key is a factor with non-`sort()`-ed levels (e.g. `factor(1:2, 2:1)` and it is joined to a character column, [#5361](https://github.com/Rdatatable/data.table/issues/5361). Thanks to @gbrunick for the report and Benjamin Schwendinger for the fix.
8282
8383
19. Spurious warnings from internal code in `cube()`, `rollup()`, and `groupingsets()` are no longer surfaced to the caller, [#6964](https://github.com/Rdatatable/data.table/issues/6964). Thanks @ferenci-tamas for the report and @venom1204 for the fix.
84-
84+
85+
20. Ellipsis elements like `..1` are correctly excluded when searching for variables in "up-a-level" syntax inside `[`, [#5460](https://github.com/Rdatatable/data.table/issues/5460). Thanks @ggrothendieck for the report and @MichaelChirico for the fix.
86+
8587
### NOTES
8688
8789
1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/.

R/data.table.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ replace_dot_alias = function(e) {
266266
if (!missing(j)) {
267267
jsub = replace_dot_alias(jsub)
268268
root = root_name(jsub)
269-
av = all.vars(jsub)
269+
# exclude '..1' etc. for #5460
270+
av = grepv("^[.][.](?:[.]|[0-9]+)$", all.vars(jsub), invert=TRUE)
270271
all..names = FALSE
271272
if ((.is_withFALSE_range(jsub, x, root, av)) ||
272273
(root %chin% c("-","!") && jsub[[2L]] %iscall% '(' && jsub[[2L]][[2L]] %iscall% ':') || ## x[, !(V8:V10)]
@@ -1298,8 +1299,8 @@ replace_dot_alias = function(e) {
12981299
SDenv = new.env(parent=parent.frame())
12991300

13001301
syms = all.vars(jsub)
1301-
syms = syms[ startsWith(syms, "..") ]
1302-
syms = syms[ substr(syms, 3L, 3L) != "." ] # exclude ellipsis
1302+
syms = syms[startsWith(syms, "..")]
1303+
syms = grepv("^[.][.](?:[.]|[0-9]+)$", syms, invert=TRUE) # exclude ellipsis and '..n' ellipsis elements
13031304
for (sym in syms) {
13041305
if (sym %chin% names_x) {
13051306
# if "..x" exists as column name, use column, for backwards compatibility; e.g. package socialmixr in rev dep checks #2779

inst/tests/tests.Rraw

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21358,3 +21358,19 @@ test(2327.1, cube(DT, .(min(value)), "var"),
2135821358
test(2327.2, cube(DT, .(as.numeric(base::min(value, na.rm=TRUE))), "var"),
2135921359
data.table(var = c("a", "b", "c", "d", NA), V1 = c(1.0, 2.0, 3.0, Inf, 1.0)),
2136021360
warning="no non-missing arguments to min")
21361+
21362+
# '..1' is ...elt(1), not a variable named '1', when doing "up-a-level" search (#5460)
21363+
DT = data.table(a=1.0)
21364+
sqrt_dot_sym = function(...) sqrt(..1)
21365+
test(2328.1, lapply(DT, function(...) sqrt(..1)), list(a=1.0))
21366+
test(2328.2, lapply(DT, sqrt_dot_sym), list(a=1.0))
21367+
test(2328.3, DT[, lapply(.SD, function(...) sqrt(..1))], data.table(a=1.0))
21368+
test(2328.4, DT[, lapply(.SD, sqrt_dot_sym)], data.table(a=1.0))
21369+
sqrt_elt_sym = function(...) sqrt(...elt(1))
21370+
# TODO(R>=3.5.0): run this unconditionally
21371+
if (!inherits(tryCatch(sqrt_elt_sym(1), error=identity), "error")) {
21372+
test(2328.5, lapply(DT, sqrt_elt_sym), list(a=1.0))
21373+
test(2328.6, lapply(DT, function(...) sqrt(...elt(1L))), list(a=1.0))
21374+
test(2328.7, DT[, lapply(.SD, sqrt_elt_sym)], data.table(a=1.0))
21375+
test(2328.8, DT[, lapply(.SD, function(...) sqrt(...elt(1L)))], data.table(a=1.0))
21376+
}

0 commit comments

Comments
 (0)