Search code examples
rtype-conversionsapply

Convert numbers to roman numerals in sapply in R


As was mentioned in the post Convert roman numerals to numbers in R there is a function for conversion from numbers to roman numerals. However, when trying to make a conversion in sapply filtering nonnumeral symbols

sequence.to_roman<-c(1,2,"V1","df",3)
sapply(sequence.to_roman, function(x) if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols")

numerals remain the same. Though it works perfectly in elementwise fashion. Is it the function as.roman or symbol representation (encoding, for example) which behaves wrong?


Solution

  • Hiho,

    i think you have to add an as.character like this:

        sapply(sequence.to_roman, function(x) as.character(if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols"))
    > sapply(sequence.to_roman, function(x) as.character(if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols"))
                 1              2             V1             df              3 
               "I"           "II" "Some symbols" "Some symbols"          "III" 
    

    looks like the shortening of the output in sapply would convert the class roman back to its numeric value by default. So converting all outputs to char first prevents this.

    try:

    lapply(sequence.to_roman, function(x) if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols")
    > lapply(sequence.to_roman, function(x) if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols")
    [[1]]
    [1] I
    
    [[2]]
    [1] II
    
    [[3]]
    [1] "Some symbols"
    
    [[4]]
    [1] "Some symbols"
    
    [[5]]
    [1] III
    

    this iw what we want, but:

    unlist(lapply(sequence.to_roman, function(x) if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols"))
    > unlist(lapply(sequence.to_roman, function(x) if(grepl("^[1-9]\\d*$",x)) as.roman(x) else "Some symbols"))
    [1] "1"            "2"            "Some symbols" "Some symbols" "3"   
    

    also gives the recodet forms.

    for a maybe more visible description what causes the problem:

    > as.roman("3")
    [1] III
    > as.character(as.roman("3"))
    [1] "III"
    > c(as.roman("3"), "test")
    [1] "3"    "test"
    > c(as.character(as.roman("3")), "test")
    [1] "III"  "test"