0
votes

Recently, I found an error in my R code which is caused by the auto coercion by R. I accidentally compare a vector of string with an integer and the code runs successfully with most of the right comparison, which makes it very hard to know the mistake at the first place. So I want to know is there anything I can do to disable this auto coercion and raise an error just like what python does.

This is how R compares two variable with different types:

If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.

For example,

'95'>90 
#[1] TRUE
'100'>90
#[1] FALSE
1
You cannot raise an error without having a ton of undesired collateral effects. What you can and should do, is to check the type of the values you are comparing and coerce them to the desired type and/or raise an error yourself. - nicola
@nicola, post as answer? - Ben Bolker
@BenBolker I posted an answer with some other detail. Thank you. - nicola

1 Answers

1
votes

In principle, one could overwrite every basic operator in R. But it's so dangerous to do so that I wouldn't recommend in basically any instance.

What you should do is to check the type of your arguments before the comparison. Say for instance you have a function like that:

f <- function(arg1, arg2, ...) {
   #here you do some stuff
   x <- something(arg1)
   y <- someotherthing(arg1, arg2)
   #here you are about to do the comparison
   #but you check the arguments beforehand
   if (typeof(x)!=typeof(y)) stop("Type mismatch")
   #if there isn't any error you continue
   z <- x > y
   ...
   return(somevalue)
}

What about the dangerous way of redefining the base operator? Here it is:

`>`<-function(e1, e2) {
    if (typeof(e1)!=typeof(e2) && (!is.numeric(e1) || !is.numeric(e2)) ) stop("Type mismatch")
    basegt<-get(">",baseenv())
    basegt(e1,e2)
}
'95'>90 
#Error in "95" > 90 : Type mismatch
95>90
#[1] TRUE

But, again, don't try this at home (and neither at work to a even greater extent).