Было не совсем ясно, действительно ли вы хотели преобразовать цифры в их альфа-эквиваленты. Если это так, то здесь гораздо более общая стратегия. В архивах rhelp есть (как минимум) две функции преобразования чисел в текст: Джим Лемон digits2text
и Джон Фокс numberstowords
. Я также переключился на gregexpr
, чтобы перейти к векторизованному подходу:
Вырезание и вставка Функция Лимона из HTML, найденная здесь работает из коробки:
> m <- gregexpr("[0-9]+", x)
> sym <- regmatches(x,m)
> regmatches(x,m) <- digits2text(as.numeric(sym[[1]]))
illion = 0
digilen = 3
digitext = three hundred forty six
[1] 6 4 3
>
> x
[1] "I like three hundred forty six ice cream cones. They're three hundred forty six percent good! I ate three hundred forty six."
Мне нужно было отредактировать числовые слова, потому что были некоторые пропущенные переводы строк, которые испортили синтаксический анализ (и я включаю успешную версию ниже этой демонстрации:
> m <- gregexpr("[0-9]+", x)
> sym <- regmatches(x,m)
> regmatches(x,m) <- numbers2words(as.numeric(sym[[1]]))
>
> x
[1] "I like three hundred forty six ice cream cones. They're three hundred forty six percent good! I ate three hundred forty six."
Функция Фокса отредактирована с: http://tolstoy.newcastle.edu.au/R/help/05/04/2715.html
numbers2words <- function(x){
helper <- function(x){
digits <- rev(strsplit(as.character(x), "")[[1]])
nDigits <- length(digits)
if (nDigits == 1) as.vector(ones[digits])
else if (nDigits == 2)
if (x <= 19) as.vector(teens[digits[1]])
else trim(paste(tens[digits[2]],
Recall(as.numeric(digits[1]))))
else if (nDigits == 3) trim(paste(ones[digits[3]], "hundred",
Recall(makeNumber(digits[2:1]))))
else {
nSuffix <- ((nDigits + 2) %/% 3) - 1
if (nSuffix > length(suffixes)) stop(paste(x, "is too large!"))
trim(paste(Recall(makeNumber(digits[
nDigits:(3*nSuffix + 1)])),
suffixes[nSuffix],
Recall(makeNumber(digits[(3*nSuffix):1]))))
}
}
trim <- function(text){
gsub("^\ ", "", gsub("\ *$", "", text))
}
makeNumber <- function(...) as.numeric(paste(..., collapse=""))
opts <- options(scipen=100)
on.exit(options(opts))
ones <- c("", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine")
names(ones) <- 0:9
teens <- c("ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", " seventeen", "eighteen", "nineteen")
names(teens) <- 0:9
tens <- c("twenty", "thirty", "forty", "fifty", "sixty",
"seventy", "eighty", "ninety")
names(tens) <- 2:9
x <- round(x)
suffixes <- c("thousand", "million", "billion", "trillion")
if (length(x) > 1) return(sapply(x, helper))
helper(x)
}