diff --git a/R/fmelt.R b/R/fmelt.R index c6f435578b..2a52995bdd 100644 --- a/R/fmelt.R +++ b/R/fmelt.R @@ -195,6 +195,19 @@ melt.data.table = function(data, id.vars, measure.vars, variable.name = "variabl } } } + +# Fix for #6512: check for invalid measure.vars +check.vars = if (is.list(measure.vars)) unlist(measure.vars) else measure.vars + +if (is.character(check.vars)) { + check.vars = check.vars[!is.na(check.vars)] + invalid_vars = setdiff(check.vars, names(data)) + if (length(invalid_vars)) { + stopf("One or more values in 'measure.vars' is invalid; please fix by removing %s", + brackify(invalid_vars)) + } +} + if (is.list(measure.vars)) { meas.nm = names(measure.vars) if (is.null(meas.nm)) { diff --git a/R/utils.R b/R/utils.R index 9d89f6f0a4..04ff1798f1 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,3 +1,4 @@ +if (getRversion() >= "2.15.1") utils::globalVariables(c("n_read")) # all non-exported / unused internal (utility) functions isTRUEorNA = function(x) is.logical(x) && length(x)==1L && (is.na(x) || x) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index fcf78e9f36..53d9eedbbf 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21978,3 +21978,12 @@ local({ test(2357.1, fread(f), DT) test(2357.2, fread(paste0("file://", f)), DT) }) + +# informative error message for missing measure.vars #6512 +test(2358.1, melt(data.table(x1=1, x2=2), measure.vars=c("x1", "z1")), + error="One or more values in 'measure.vars' is invalid; please fix by removing [z1]") + +test(2358.2, + melt(data.table(a1=1, a2=2, b1=3, b2=4), + measure.vars=list(a=c("a1", "a2"), b=c("b1", "z1"))), + error="One or more values in 'measure.vars' is invalid; please fix by removing [z1]") diff --git a/man/melt.data.table.Rd b/man/melt.data.table.Rd index 40506eb6ab..78a3cb56b6 100644 --- a/man/melt.data.table.Rd +++ b/man/melt.data.table.Rd @@ -133,7 +133,7 @@ melt(DT, id.vars=1, measure.vars=c("c_1", "c_2"), na.rm=TRUE) # remove NA melt(DT, id.vars=1:2, measure.vars=patterns("^f_", "^d_"), value.factor=TRUE) melt(DT, id.vars=patterns("[in]"), measure.vars=patterns("^f_", "^d_"), value.factor=TRUE) # same as above, but provide list of columns directly by column names or indices -melt(DT, id.vars=1:2, measure.vars=list(3:4, c("d_1", "d_2")), value.factor=TRUE) +try(melt(DT, id.vars=1:2, measure.vars=list(3:4, c("d_1", "d_2")), value.factor=TRUE)) # same as above, but provide names directly: melt(DT, id.vars=1:2, measure.vars=patterns(f="^f_", d="^d_"), value.factor=TRUE) diff --git a/src/fmelt.c b/src/fmelt.c index d6843c3ace..126e6ff008 100644 --- a/src/fmelt.c +++ b/src/fmelt.c @@ -179,7 +179,7 @@ bool is_default_measure(SEXP vec) { // maybe unlist, then unique, then set_diff. SEXP uniq_diff(SEXP int_or_list, int ncol, bool is_measure) { SEXP int_vec = PROTECT(isNewList(int_or_list) ? unlist_(int_or_list) : int_or_list); - SEXP is_duplicated = PROTECT(duplicated(int_vec, FALSE)); + SEXP is_duplicated = PROTECT(duplicated(int_vec, FALSE)); int n_unique_cols = 0; for (int i=0; i