Convert roman numerals to numbers in R

你离开我真会死。 提交于 2019-11-28 10:46:10

as.roman() returns an object of class roman, so R recognizes it as such. You can directly turn it back into an Arabic numeral with as.numeric(). If you have a string that meets the criteria such that it could be a valid roman numeral, you can coerce it to a class roman object with as.roman(), and then coerce it into an Arabic numeral by composing the coercion functions. Consider:

> as.roman(79)
[1] LXXIX
> x <- as.roman(79)
> x
[1] LXXIX
> str(x)
Class 'roman'  int 79
> as.roman("LXXIX")
[1] LXXIX
> as.numeric(as.roman("LXXIX"))
[1] 79

From as.roman code you can find .roman2numeric and its code can be seen if you run getAnywhere(".roman2numeric")

The code is:

function (x) 
{
  romans <- c("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", 
              "IX", "V", "IV", "I")
  numbers <- c(1000L, 900L, 500L, 400L, 100L, 90L, 50L, 40L, 
               10L, 9L, 5L, 4L, 1L)
  out <- integer(length(x))
  ind <- is.na(x)
  out[ind] <- NA
  if (any(!ind)) {
    y <- toupper(x[!ind])
    y <- gsub("CM", "DCCCC", y)
    y <- gsub("CD", "CCCC", y)
    y <- gsub("XC", "LXXXX", y)
    y <- gsub("XL", "XXXX", y)
    y <- gsub("IX", "VIIII", y)
    y <- gsub("IV", "IIII", y)
    ok <- grepl("^M{,3}D?C{,4}L?X{,4}V?I{,4}$", y)
    if (any(!ok)) {
      warning(sprintf(ngettext(sum(!ok), "invalid roman numeral: %s", 
                               "invalid roman numerals: %s"), paste(x[!ind][!ok], 
                                                                    collapse = " ")), domain = NA)
      out[!ind][!ok] <- NA
    }
    if (any(ok)) 
      out[!ind][ok] <- sapply(strsplit(y[ok], ""), function(z) as.integer(sum(numbers[match(z, 
                                                                                            romans)])))
  }
  out
}

You can access to .roman2numeric and convert roman number to decimal numbers the way @rawr suggested in his/her comment.

> utils:::.roman2numeric("III")
[1] 3
> utils:::.roman2numeric("XII")
[1] 12
> utils:::.roman2numeric("LXXIX")
[1] 79

The roman numbers in R are, according to the docs:

objects of class "roman" which are internally represented as integers, and have suitable methods for printing, formatting, subsetting, and coercion to character.

You should therefore be able to get the integer value back using as.integer():

as.integer(as.roman(79)+as.roman(12))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!