142

I generally prefer to code R so that I don't get warnings, but I don't know how to avoid getting a warning when using as.numeric to convert a character vector.

For example:

x <- as.numeric(c("1", "2", "X"))

Will give me a warning because it introduced NAs by coercion. I want NAs introduced by coercion - is there a way to tell it "yes this is what I want to do". Or should I just live with the warning?

Or should I be using a different function for this task?

Corvus
  • 7,548
  • 9
  • 42
  • 68
  • 8
    See `?suppressWarnings` perhaps? – A5C1D2H2I1M1N2O1R2T1 Feb 20 '13 at 16:32
  • 4
    What is the problem with this warning? Generally it gives valuable information. I prefer a more verbose output in the R console to nasty surprises. – Roland Feb 20 '13 at 16:53
  • 13
    @Roland I totally agree, but the usefulness of warnings diminishes if you get used to just ignoring them. That's why I generally like to "tackle" the warnings. In this case, I will ALWAYS generate warnings, and lots of them - my data is coming in as strings with "X" representing NA, and so the function is doing exactly what I want it to do. I wanted to says "Thanks for letting me know, but it's ok I know what I'm doing". `suppressWarnings` seems perfect. – Corvus Feb 20 '13 at 16:56
  • 6
    You know that `read.table` accepts an argument `na.strings`? – Roland Feb 20 '13 at 17:03
  • It's useful to suppress them if you already have a work around to a known bug in a library. That's how I'm going to use this! – Clem Wang Jan 07 '19 at 21:25

5 Answers5

161

Use suppressWarnings():

suppressWarnings(as.numeric(c("1", "2", "X")))
[1]  1  2 NA

This suppresses warnings.

Andrie
  • 176,377
  • 47
  • 447
  • 496
  • 1
    Although this is the preferred response, the answer by jangorecki below seems, to me, more solid. – Ian Jul 06 '20 at 15:29
40

suppressWarnings() has already been mentioned. An alternative is to manually convert the problematic characters to NA first. For your particular problem, taRifx::destring does just that. This way if you get some other, unexpected warning out of your function, it won't be suppressed.

> library(taRifx)
> x <- as.numeric(c("1", "2", "X"))
Warning message:
NAs introduced by coercion 
> y <- destring(c("1", "2", "X"))
> y
[1]  1  2 NA
> x
[1]  1  2 NA
Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • 6
    I know this is an old thread and `destring` works perfectly for op's example, but one caveat for anyone who sees this thread in the future is that `destring` works differently from `as.numeric` when the target string is a mixture of string and numeric : that is, `destring("x1")` gives `1` but `as.numeric("x1")` gives `NA` – Hong Mar 17 '20 at 20:52
  • Error in library(taRifx): there is no package called ‘taRifx’ There is only Zuul. https://knowyourmeme.com/memes/there-is-no-dana-only-zuul – Urasquirrel Jun 19 '22 at 03:31
38

In general suppressing warnings is not the best solution as you may want to be warned when some unexpected input will be provided.
Solution below is wrapper for maintaining just NA during data type conversion. Doesn't require any package.

    as.num = function(x, na.strings = "NA") {
        stopifnot(is.character(x))
        na = x %in% na.strings
        x[na] = "0"
        x = as.numeric(x)
        x[na] = NA_real_
        x
    }
    as.num(c("1", "2", "X"), na.strings="X")
    #[1]  1  2 NA
jangorecki
  • 16,384
  • 4
  • 79
  • 160
  • 6
    This is the best answer. Using `suppressWarnings()` is generally a bad idea, because we sometimes need to see those warnings. – keberwein Sep 26 '17 at 18:49
1

I have slightly modified the jangorecki function for the case where we may have a variety of values that cannot be converted to a number. In my function, a template search is performed and if the template is not found, FALSE is returned.! before gperl, it means that we need those vector elements that do not match the template. The rest is similar to the as.num function. Example:

as.num.pattern <- function(x, pattern){
  stopifnot(is.character(x))
  na = !grepl(pattern, x)
  x[na] = -Inf
  x = as.numeric(x)
  x[na] = NA_real_
  x
}

as.num.pattern(c('1', '2', '3.43', 'char1', 'test2', 'other3', '23/40', '23, 54 cm.'))

[1] 1.00 2.00 3.43   NA   NA   NA   NA   NA
  • The example will not run presently because `pattern` has not been specified. `as.num.pattern(c('1', '2', '3.43', NA, 'char1', 'test2', 'other3', '23/40', '23, 54 cm.'),pattern = "^[0-9\\.,]+$")` will reproduce the results. – ckx Jun 17 '22 at 09:42
0

One way to silence only particular warnings is to use the approach at Suppress warning based on their position in warning list or based on a regular expression in R

Here's a full example for the specific OP's case:

with_warning_handler <- function(reg, ...)
{
  withCallingHandlers(..., warning = function(w)
    {
        condition <- conditionMessage(w)
        if(grepl(reg, condition)) invokeRestart("muffleWarning")
  })
}


with_warning_handler("NAs introduced by coercion",
  x <- as.numeric(c("1", "2", "X"))
)
scottkosty
  • 2,410
  • 1
  • 16
  • 22