Search code examples
rdivisioncoercion

How to compute a check digit for a large number in R?


I must add a 2-digit check (remaining of division by 97) to numbers such as 52/200005/0001 (slashes must be ignored).

My code is the following, but it fails because of too big number:

AppendCheckDigits <- function (x) {
  stopifnot(is.character(x) & length(x) == 1 & nchar(x) == 14)
  cd <- as.integer(paste(substring(x, 1, 2),
                         substring(x, 4, 9),
                         substring(x, 11, 14), sep="")) %% 97
  paste(x, "/", cd, sep="")
}

Test it with:

AppendCheckDigits("52/200005/0001")

How can I solve it?


Solution

  • Objects of class integer are restricted to about 2*10^9. You should use as.numeric instead of as.integer in your function :

    AppendCheckDigits <- function (x) {
      stopifnot(is.character(x) & length(x) == 1 & nchar(x) == 14)
      cd <- as.numeric(paste(substring(x, 1, 2),
                             substring(x, 4, 9),
                             substring(x, 11, 14), sep="")) %% 97
      paste(x, "/", cd, sep="")
    }
    

    Then :

    > AppendCheckDigits("52/200005/0001")
    [1] "52/200005/0001/43"
    

    Note that you could vectorize and simplify your function this way, for example :

    AppendCheckDigits <- function (x) {
      stopifnot(is.character(x) & nchar(x) == rep(14,length(x)))
      num <- as.numeric(gsub("/","", x)) %% 97
      return(paste0(x, "/", num))
    }
    

    Then :

    > AppendCheckDigits(c("52/200005/0001", "52/200005/0021"))
    [1] "52/200005/0001/43" "52/200005/0021/63"