2014-10-03 6 views
2

Я должен добавить двузначную проверку (оставшуюся деление на 97) на такие цифры, как 52/200005/0001 (слэши должны игнорироваться).Как вычислить контрольную цифру для большого числа в R?

Мой код заключается в следующем, но она не из-за слишком большого числа:

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

проверить его с:

AppendCheckDigits("52/200005/0001") 

Как я могу решить эту проблему?

ответ

6

Объекты класса integer ограничены примерно 2 * 10^9. Вы должны использовать as.numeric вместо as.integer в функции:

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

Тогда:

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

Обратите внимание, что вы могли бы векторизации и упростить вашу функцию так, например:

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

Тогда :

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

Что еще я могу сказать, чем «Я не ожидал такого идеального ответа, ясного и обширного»? Не знаю! ;-) – user3341592

+0

Код AppendCheckDigits <- function (x) { stopifnot (is.character (x) & nchar (x) == 14) num <- as.numeric (gsub ("/", "", x)) %% 97 paste0 (x, "/", num), похоже, работает так же, как ваш. Здесь нет «rep» и «return». Действительно ли они важны? } – user3341592

+0

@ user3341592 Нет, вы правы, с правилом утилизации нет необходимости использовать 'rep' здесь. Ваш код в порядке и чище. – juba

2

Вариант ответа @ Джуба, используя путь к файлу и заменял все не цифры:

AppendCheckDigits <- function (x) { 
    stopifnot(is.character(x) & nchar(x) == rep(14,length(x))) 
    num <- as.numeric(gsub("\\D","", x)) %% 97 
    file.path(x, num) 
} 

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

Больше для различных способов, которыми это может быть приближенным, если будущая поисковой была аналогичной проблема, это может дать альтернативы.

+0

Да, вам очень приятно поставить альтернативы здесь. Такие ответы читаются и читаются и оказываются полезными! – user3341592