Reputation: 83
I want to transform large numbers (below 10.000) to roman. I know the as.roman function. But that does only go to 3899.
Is it possible to change in the source code in this function and force it to transform the larger numbers - or is it possible to write a new function?
I am running R 3.3.0.
Best, Sander.
Upvotes: 1
Views: 222
Reputation: 35324
A while back I wrote an integer-to-Roman conversion function in Perl. I just rewrote it in R for this answer. Note that I use the newfangled strrep()
function which I believe was only added in 3.3.0.
integerToRoman <- function(x) {
x <- as.integer(x);
neg <- x<0L;
x <- abs(x);
cnt <- integer(length(x));
res <- rep('',length(x));
if (any(m <- x==0L)) { res[m] <- 'nulla'; };
if (any(m <- x>=1000L)) { cnt[m] <- x[m]%/%1000L; x[m] <- x[m]%%1000L; res[m] <- strrep('M',cnt[m]); };
if (any(m <- x>=900L)) { res[m] <- paste0(res[m],'CM'); x[m] <- x[m]-900L; };
if (any(m <- x>=500L)) { res[m] <- paste0(res[m],'D'); x[m] <- x[m]-500L; };
if (any(m <- x>=400L)) { res[m] <- paste0(res[m],'CD'); x[m] <- x[m]-400L; };
if (any(m <- x>=100L)) { cnt[m] <- x[m]%/%100L; x[m] <- x[m]%%100L; res[m] <- paste0(res[m],strrep('C',cnt[m])); };
if (any(m <- x>=90L)) { res[m] <- paste0(res[m],'XC'); x[m] <- x[m]-90L; };
if (any(m <- x>=50L)) { res[m] <- paste0(res[m],'L'); x[m] <- x[m]-50L; };
if (any(m <- x>=40L)) { res[m] <- paste0(res[m],'XL'); x[m] <- x[m]-40L; };
if (any(m <- x>=10L)) { cnt[m] <- x[m]%/%10L; x[m] <- x[m]%%10L; res[m] <- paste0(res[m],strrep('X',cnt[m])); };
if (any(m <- x>=9L)) { res[m] <- paste0(res[m],'IX'); x[m] <- x[m]-9L; };
if (any(m <- x>=5L)) { res[m] <- paste0(res[m],'V'); x[m] <- x[m]-5L; };
if (any(m <- x>=4L)) { res[m] <- paste0(res[m],'IV'); x[m] <- x[m]-4L; };
if (any(m <- x>=1L)) res[m] <- paste0(res[m],strrep('I',x[m]));
if (any(neg)) res[neg] <- paste0('-',res[neg]);
res;
}; ## end integerToRoman()
Demo:
set.seed(319072L); data.frame(int=x <- sample(seq(0L,5e3L),20L),roman=integerToRoman(x));
## int roman
## 1 614 DCXIV
## 2 4825 MMMMDCCCXXV
## 3 6 VI
## 4 4721 MMMMDCCXXI
## 5 9 IX
## 6 3333 MMMCCCXXXIII
## 7 2114 MMCXIV
## 8 4861 MMMMDCCCLXI
## 9 1042 MXLII
## 10 3609 MMMDCIX
## 11 417 CDXVII
## 12 241 CCXLI
## 13 3 III
## 14 4952 MMMMCMLII
## 15 1370 MCCCLXX
## 16 1789 MDCCLXXXIX
## 17 3730 MMMDCCXXX
## 18 2275 MMCCLXXV
## 19 1139 MCXXXIX
## 20 4898 MMMMDCCCXCVIII
Upvotes: 4