Skip to content

Commit 495ffd4

Browse files
Only warn once about '...' contents in merge.data.table (#7091)
* only warn once about '...' contents * pluralization mess * fix old tests * new tests * break up double-ngettext * missing ',' * fix vestige * also missing n_named * sprintf() to fill out; fix some tests * missing 's' * push logic into helper to tidy up merge body
1 parent 3b00b35 commit 495ffd4

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

R/merge.R

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,8 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL
6363
}
6464

6565
# warn about unused arguments #2587
66-
if (length(list(...))) {
67-
ell = as.list(substitute(list(...)))[-1L]
68-
for (n in setdiff(names(ell), "")) warningf("Unknown argument '%s' has been passed.", n)
69-
unnamed_n = length(ell) - sum(nzchar(names(ell)))
70-
if (unnamed_n)
71-
warningf("Passed %d unknown and unnamed arguments.", unnamed_n)
72-
}
66+
.maybe_warn_merge_dots(...)
67+
7368
# with i. prefix in v1.9.3, this goes away. Left here for now ...
7469
## sidestep the auto-increment column number feature-leading-to-bug by
7570
## ensuring no names end in ".1", see unit test
@@ -125,3 +120,28 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL
125120
setattr(dt, "class", class_x)
126121
dt
127122
}
123+
124+
.maybe_warn_merge_dots <- function(...) {
125+
# TODO(R >= 3.5.0): use ...length()
126+
n_dots <- length(dots <- list(...))
127+
if (!n_dots) return(invisible())
128+
129+
nm <- names(dots)
130+
if (is.null(nm)) {
131+
warningf(ngettext(n_dots, "merge.data.table() received %d unnamed argument in '...' which will be ignored.",
132+
"merge.data.table() received %d unnamed arguments in '...' which will be ignored."),
133+
n_dots)
134+
} else {
135+
named_idx = nzchar(nm)
136+
if (all(named_idx)) {
137+
warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s",
138+
"merge.data.table() received %d unknown keyword arguments which will be ignored: %s"),
139+
n_dots, brackify(nm))
140+
} else {
141+
n_named <- sum(named_idx)
142+
unnamed_clause <- sprintf(ngettext(n_dots - n_named, "%d unnamed argument in '...'", "%d unnamed arguments in '...'"), n_dots - n_named)
143+
named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword arguments"), n_named)
144+
warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx]))
145+
}
146+
}
147+
}

inst/tests/tests.Rraw

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17981,14 +17981,26 @@ test(2229.6, fread(testDir("multi-file.zip")), error="Compressed files containin
1798117981
x = data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5), data = 1:5)
1798217982
y = data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5), data = 1:5)
1798317983
DT = as.data.table(x)
17984-
test(2230.1, setDF(merge(DT, y, by="k2", incomparables=NA)), merge(x, y, by="k2", incomparables=NA))
17985-
test(2230.2, setDF(merge(DT, y, by="k2", incomparables=c(NA,4))), merge(x, y, by="k2", incomparables=c(NA,4)))
17986-
test(2230.3, setDF(merge(DT, y, by="k2", incomparables=c(4,5))), merge(x, y, by="k2", incomparables=c(4,5)))
17987-
test(2230.4, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge(x, y, by="k2", incomparables=c(1,NA,4,5)))
17988-
test(2230.5, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5)))
17989-
test(2230.6, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="Unknown argument 'unk' has been passed.")
17990-
test(2230.7, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L),
17991-
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "Passed 1 unknown and unnamed arguments."))
17984+
test(2230.01, setDF(merge(DT, y, by="k2", incomparables=NA)), merge(x, y, by="k2", incomparables=NA))
17985+
test(2230.02, setDF(merge(DT, y, by="k2", incomparables=c(NA,4))), merge(x, y, by="k2", incomparables=c(NA,4)))
17986+
test(2230.03, setDF(merge(DT, y, by="k2", incomparables=c(4,5))), merge(x, y, by="k2", incomparables=c(4,5)))
17987+
test(2230.04, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge(x, y, by="k2", incomparables=c(1,NA,4,5)))
17988+
test(2230.05, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5)))
17989+
test(2230.06, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="1 unknown keyword argument which will be ignored: [unk]")
17990+
test(2230.07, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L),
17991+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument in '...' which will be ignored."))
17992+
test(2230.08, merge(DT, y, by="k2", unk1=1, unk2=2), merge(DT, y, by="k2"), warning="2 unknown keyword arguments which will be ignored: [unk1, unk2]")
17993+
test(2230.09, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L, 2L),
17994+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments in '...' which will be ignored."))
17995+
test(2230.10, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk=1L, 2L),
17996+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument .*1 unknown keyword argument,.*\\[unk\\]"))
17997+
test(2230.11, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk1=1L, unk2=2L, 3L),
17998+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument .*2 unknown keyword arguments.*\\[unk1, unk2\\]"))
17999+
test(2230.12, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk=1L, 2L, 3L),
18000+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments.*1 unknown keyword argument,.*\\[unk\\]"))
18001+
test(2230.13, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk1=1L, unk2=2L, 3L, 4L),
18002+
merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments.*2 unknown keyword arguments.*\\[unk1, unk2\\]"))
18003+
1799218004

1799318005
# weighted.mean GForce optimized, #3977
1799418006
old = options(datatable.optimize=1L)

0 commit comments

Comments
 (0)