在R中,as.roman在基本设置中有一个很棒的功能:
as.roman(79)
# [1] LXXIX
Run Code Online (Sandbox Code Playgroud)
是否有将罗马数字转换为数字的反函数?
(我知道我可以自己写,但我更喜欢使用已经准备好或最好是标准的功能,不幸的是找不到一个.标准库或包功能是首选解决方案)
gun*_*ica 31
as.roman()返回罗马类的对象,因此R识别它.您可以直接将其转换为阿拉伯数字as.numeric().如果您的字符串符合条件,使其可以是有效的罗马数字,则可以将其强制转换为罗马式对象as.roman(),然后通过编写强制函数将其强制转换为阿拉伯数字.考虑:
> 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
Run Code Online (Sandbox Code Playgroud)
Jil*_*ina 10
从as.roman您可以找到.roman2numeric的代码中,如果您运行,可以看到它的代码getAnywhere(".roman2numeric")
代码是:
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
}
Run Code Online (Sandbox Code Playgroud)
您可以.roman2numeric像@rawr在他/她的评论中所建议的那样访问并将罗马数转换为十进制数.
> utils:::.roman2numeric("III")
[1] 3
> utils:::.roman2numeric("XII")
[1] 12
> utils:::.roman2numeric("LXXIX")
[1] 79
Run Code Online (Sandbox Code Playgroud)
roman根据文档,R中的数字是:
类的对象,
"roman"内部表示为整数,并具有适合打印,格式化,子集化和强制的方法character.
因此,您应该能够使用as.integer()以下方法获取整数值:
as.integer(as.roman(79)+as.roman(12))
Run Code Online (Sandbox Code Playgroud)