Corvus
Corvus

Reputation: 8049

How to avoid warning when introducing NAs by coercion

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?

Upvotes: 148

Views: 280301

Answers (6)

AdamO
AdamO

Reputation: 4930

This could be a job for regex, but depends a lot on the types of non-numeric values. You have to be careful not to delete - for negative or . for decimal, and it gets worse when you consider scientific notation. In my case, I'm often dealing with character and numeric such as QPCR = c('0.012', '0.001', 'BLLOD'). So I can do:

QPCRN = as.numeric(gsub('[a-zA-Z]', '', QPCR))

the trick is that as.numeric('') goes to NA without a warning.

I quite prefer this to "SuppressWarnings" because the useR is forced to at least understand the types of other character values.

Upvotes: 2

scottkosty
scottkosty

Reputation: 2570

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

EDIT: Note that this approach is not robust to locale changes/translations (thanks to Ben Bolker for pointing this out).

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"))
)

Upvotes: 0

jangorecki
jangorecki

Reputation: 16697

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

Upvotes: 42

Vladislav Shufinskiy
Vladislav Shufinskiy

Reputation: 23

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

Upvotes: 1

Ari B. Friedman
Ari B. Friedman

Reputation: 72731

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

Upvotes: 39

Andrie
Andrie

Reputation: 179418

Use suppressWarnings():

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

This suppresses warnings.

Upvotes: 165

Related Questions