diff --git a/R/between.R b/R/between.R index 82703ed7b..e96434732 100644 --- a/R/between.R +++ b/R/between.R @@ -5,14 +5,14 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE) if (is.logical(upper)) upper = as.integer(upper) # typically NA (which is logical type) is.px = function(x) inherits(x, "POSIXct") is.i64 = function(x) inherits(x, "integer64") # this is true for nanotime too - # POSIX special handling to auto coerce character + # POSIXct special handling to auto coerce character if (is.px(x) && (is.character(lower) || is.character(upper))) { tz = attr(x, "tzone", exact=TRUE) if (is.null(tz)) tz = "" if (is.character(lower)) lower = tryCatch(as.POSIXct(lower, tz=tz), error=function(e)stopf( - "'between' function the 'x' argument is a POSIX class while '%s' was not, coercion to POSIX failed with: %s", 'lower', e$message)) + "The 'x' argument of the 'between' function is POSIXct while '%s' was not, coercion to POSIXct failed with: %s", 'lower', conditionMessage(e))) if (is.character(upper)) upper = tryCatch(as.POSIXct(upper, tz=tz), error=function(e)stopf( - "'between' function the 'x' argument is a POSIX class while '%s' was not, coercion to POSIX failed with: %s", 'upper', e$message)) + "The 'x' argument of the 'between' function is POSIXct while '%s' was not, coercion to POSIXct failed with: %s", 'upper', conditionMessage(e))) stopifnot(is.px(x), is.px(lower), is.px(upper)) # nocov # internal } # POSIX check timezone match diff --git a/R/data.table.R b/R/data.table.R index a4473cb94..fe41ed2d3 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -292,7 +292,7 @@ replace_dot_alias = function(e) { root = root_name(jsub) } else if (length(jsub) > 2L && jsub[[2L]] %iscall% ":=") { #2142 -- j can be {} and have length 1 - stopf("You have wrapped := with {} which is ok but then := must be the only thing inside {}. You have something else inside {} as well. Consider placing the {} on the RHS of := instead; e.g. DT[,someCol:={tmpVar1<-...;tmpVar2<-...;tmpVar1*tmpVar2}") + stopf("You have wrapped := with {} which is ok but then := must be the only thing inside {}. You have something else inside {} as well. Consider placing the {} on the RHS of := instead; e.g. DT[,someCol:={tmpVar1<-...;tmpVar2<-...;tmpVar1*tmpVar2}]") } } if (root=="eval" && !any(all.vars(jsub[[2L]]) %chin% names_x)) { @@ -409,7 +409,7 @@ replace_dot_alias = function(e) { "'%s' is not found in calling scope and it is not a column name either", as.character(isub) ) else gettextf( - "'%s' is not found in calling scope, but it is a column of type %s. If you wish to select rows where that column contains TRUE, or perhaps that column contains row numbers of itself to select, try DT[(col)], DT[DT$col], or DT[col==TRUE} is particularly clear and is optimized", + "'%s' is not found in calling scope, but it is a column of type %s. If you wish to select rows where that column contains TRUE, or perhaps that column contains row numbers of itself to select, try DT[(col)], DT[DT$col], or DT[col==TRUE] is particularly clear and is optimized", as.character(isub), typeof(col) ) stopf("%s. When the first argument inside DT[...] is a single symbol (e.g. DT[var]), data.table looks for var in calling scope.", msg) @@ -1040,7 +1040,7 @@ replace_dot_alias = function(e) { if (anyNA(.SDcols)) stopf(".SDcols missing at the following indices: %s", brackify(which(is.na(.SDcols)))) if (is.logical(.SDcols)) { - if (length(.SDcols)!=length(x)) stopf(".SDcols is a logical vector length %d but there are %d columns", length(.SDcols), length(x)) + if (length(.SDcols)!=length(x)) stopf(".SDcols is a logical vector of length %d but there are %d columns", length(.SDcols), length(x)) ansvals = which_(.SDcols, !negate_sdcols) ansvars = sdvars = names_x[ansvals] } else if (is.numeric(.SDcols)) { diff --git a/R/duplicated.R b/R/duplicated.R index 0aad2ebdd..12c53f934 100644 --- a/R/duplicated.R +++ b/R/duplicated.R @@ -102,7 +102,7 @@ anyDuplicated.data.table = function(x, incomparables=FALSE, fromLast=FALSE, by=s uniqueN = function(x, by = if (is.list(x)) seq_along(x) else NULL, na.rm=FALSE) { # na.rm, #1455 if (is.null(x)) return(0L) if (!is.atomic(x) && !is.data.frame(x)) - stopf("x must be an atomic vector or data.frames/data.tables") + stopf("x must be an atomic vector or a data.frame/data.table") if (is.atomic(x)) { if (is.logical(x)) return(.Call(CuniqueNlogical, x, na.rm=na.rm)) x = as_list(x) diff --git a/R/fmelt.R b/R/fmelt.R index 1730224b7..3f924c2e4 100644 --- a/R/fmelt.R +++ b/R/fmelt.R @@ -14,7 +14,7 @@ melt.default = function(data, ..., na.rm = FALSE, value.name = "value") { data_name = deparse(substitute(data)) ns = tryCatch(getNamespace("reshape2"), error=function(e) stopf("The %1$s generic in data.table has been passed a %2$s, but data.table::%1$s currently only has a method for data.tables. Please confirm your input is a data.table, with setDT(%3$s) or as.data.table(%3$s). If you intend to use a method from reshape2, try installing that package first, but do note that reshape2 is superseded and is no longer actively developed.", "melt", class1(data), data_name)) - warningf("The %1$s generic in data.table has been passed a %2$s and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is superseded and is no longer actively developed, and this redirection is now deprecated. To continue using melt methods from reshape2 while both libraries are attached, e.g. melt.list, you can prepend the namespace, i.e. reshape2::%1$s(%3$s). In the next version, this warning will become an error.", "melt", class1(data), data_name) + warningf("The %1$s generic in data.table has been passed a %2$s and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is superseded and is no longer actively developed, and this redirection is now deprecated. To continue using melt methods from reshape2 while both packages are attached, e.g. melt.list, you can prepend the namespace, i.e. reshape2::%1$s(%3$s). In the next version, this warning will become an error.", "melt", class1(data), data_name) ns$melt(data, ..., na.rm=na.rm, value.name=value.name) # nocov end } diff --git a/R/onAttach.R b/R/onAttach.R index 7a4a9be3e..d8393d7a6 100644 --- a/R/onAttach.R +++ b/R/onAttach.R @@ -24,8 +24,12 @@ else packageStartupMessagef("data.table %s using %d threads (see ?getDTthreads). ", v, nth, appendLF=FALSE) packageStartupMessagef("Latest news: r-datatable.com") - if (gettext("TRANSLATION CHECK") != "TRANSLATION CHECK") - packageStartupMessagef("**********\nRunning data.table in English; package support is available in English only. When searching for online help, be sure to also check for the English error message. This can be obtained by looking at the po/R-.po and po/.po files in the package source, where the native language and English error messages can be found side-by-side\n**********") + if (gettext("TRANSLATION CHECK") != "TRANSLATION CHECK") { + packageStartupMessagef( + "**********\nRunning data.table in English; package support is available in English only. When searching for online help, be sure to also check for the English error message. This can be obtained by looking at the po/R-.po and po/.po files in the package source, where the native language and English error messages can be found side-by-side.%s\n**********", + if (exists('Sys.setLanguage', envir=baseenv())) " You can also try calling Sys.setLanguage('en') prior to reproducing the error message." else "" + ) + } if (dev && (Sys.Date() - as.Date(d))>28L) packageStartupMessagef("**********\nThis development version of data.table was built more than 4 weeks ago. Please update: data.table::update_dev_pkg()\n**********") if (!.Call(ChasOpenMP)) { diff --git a/R/onLoad.R b/R/onLoad.R index 396d66e05..ef96849e8 100644 --- a/R/onLoad.R +++ b/R/onLoad.R @@ -24,7 +24,8 @@ if (dllV != RV) { dll = if (.Platform$OS.type=="windows") "dll" else "so" # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478 - stopf("The data_table.%s version (%s) does not match the package (%s). Please close all R sessions to release the old %s and reinstall data.table in a fresh R session. The root cause is that R's package installer can in some unconfirmed circumstances leave a package in a state that is apparently functional but where new R code is calling old C code silently: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478. Once a package is in this mismatch state it may produce wrong results silently until you next upgrade the package. Please help by adding precise circumstances to 17478 to move the status to confirmed. This mismatch between R and C code can happen with any package not just data.table. It is just that data.table has added this check.", dll, dllV, RV, toupper(dll)) + # TODO(R>=4.0.0): Remove or adjust this message once we're sure all users are unaffected + stopf("The data_table.%s version (%s) does not match the package (%s). Please close all R sessions to release the old %s and reinstall data.table in a fresh R session. Prior to R version 3.6.0 patched, R's package installer could leave a package in an apparently functional state where new R code was calling old C code silently: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478. Once a package is in this mismatch state it may produce wrong results silently until you next upgrade the package. This mismatch between R and C code can happen with any package not just data.table. It is just that data.table has added this check.", dll, dllV, RV, toupper(dll)) } builtPath = system.file("Meta", "package.rds", package="data.table") if (builtPath != "" && !identical(session_r_version>="4.0.0", (build_r_version <- readRDS(builtPath)$Built$R)>="4.0.0")) { diff --git a/R/setops.R b/R/setops.R index c431c944d..324195b15 100644 --- a/R/setops.R +++ b/R/setops.R @@ -6,7 +6,7 @@ setdiff_ = function(x, y, by.x=seq_along(x), by.y=seq_along(y), use.names=FALSE) by.x = colnamesInt(x, by.x, check_dups=TRUE) if (!nrow(y)) return(unique(x, by=by.x)) by.y = colnamesInt(y, by.y, check_dups=TRUE) - if (length(by.x) != length(by.y)) stopf("length(by.x) != length(by.y)") + if (length(by.x) != length(by.y)) stopf("length(by.x) != length(by.y)", domain=NA) # factor in x should've factor/character in y, and vice-versa for (a in seq_along(by.x)) { lc = by.y[a] diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 216674504..2b3958acd 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -7539,7 +7539,7 @@ test(1538.2, !is.unsorted(tables(order.col="NROW")$NROW), output="Total:") # uniqueN not support list-of-list: reverted #1224 d1 <- data.table(a = 1:4, l = list(list(letters[1:2]),list(Sys.time()),list(1:10),list(letters[1:2]))) -test(1539, d1[,uniqueN(l)], error = "x must be an atomic vector or data.frames/data.tables") +test(1539, d1[,uniqueN(l)], error = "x must be an atomic vector or a data.frame/data.table") # feature #1130 - joins without setting keys # can't test which=TRUE with DT1.copy's results.. @@ -14920,10 +14920,10 @@ options(old) # exceptions in char to POSIX coercion dn = 'aa2016-09-18 08:00:00' -test(2038.14, between(x, dn, up), error="coercion to POSIX failed") +test(2038.14, between(x, dn, up), error="coercion to POSIXct failed") dn = '2016-09-18 08:00:00' up = 'bb2016-09-18 09:00:00' -test(2038.15, between(x, dn, up), error="coercion to POSIX failed") +test(2038.15, between(x, dn, up), error="coercion to POSIXct failed") # exceptions due to timezone mismatch x = as.POSIXct("2016-09-18 07:00:00", tz="UTC") + 0:10*60*15