2014-01-14 14 views
17

In R gibt es eine große Funktion as.roman in dem sehr Basis-Setup:Konvertieren römische Ziffern zu Zahlen in R

as.roman(79) 
# [1] LXXIX 

Gibt es eine inverse Funktion, die römischen Ziffern in Zahlen umwandeln würde?

(ich weiß, ich kann es selbst schreiben, aber ich ziehe schon vorbereitet oder vorzugsweise Standardfunktionen verwenden, leider nicht finden kann. Standardbibliothek oder Paket-Funktion ist eine bevorzugte Lösung)

Antwort

28

as.roman() gibt ein Objekt von Klasse römisch, so erkennt R es als solches. Sie können es direkt in eine arabische Zahl mit as.numeric() zurückdrehen. Wenn Sie eine Zeichenkette haben, die den Kriterien entspricht, dass es sich um eine gültige römische Zahl handeln könnte, können Sie sie mit as.roman() zu einem römischen Objekt der Klasse zwingen und dann durch das Erstellen der Zwangsfunktionen in eine arabische Zahl erzwingen. Betrachten:

> 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 
6

Die roman Zahlen in R ist, gemäß the docs:

Objekte der Klasse "roman", die intern als ganze Zahlen dargestellt werden, und haben geeignete Verfahren zum Drucken, Formatierung, subsetting, und Zwang zu character.

Sie sollten daher in der Lage sein, wieder den Integer-Wert erhalten as.integer() mit:

as.integer(as.roman(79)+as.roman(12)) 
10

Von as.roman Code, den Sie .roman2numeric und seinen Code finden können, wenn Sie getAnywhere(".roman2numeric")

Der Code ausführen zu sehen ist:

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 
} 

Sie c ein Zugang zu .roman2numeric und konvertieren römische Zahl in Dezimalzahlen die Art, wie @raw in seinem/ihrem Kommentar vorgeschlagen.

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