Alex Rivera | Logout

Conditional gsub replacement

Asked 2012-01-02T17:05:11.147
10

I have text data (in R) and want to replace some characters with other characters in a data frame. I thought this would be an easy task using strsplit on spaces and create a vector that can I can then use matching (%in%) which can then be pasted back together. But then I thought about punctuation. There's no space between the last word of a sentence and the punctuation at the end.

I figure there's probably a more simple way to achieve what I want than the convoluted mess that's becoming my code. I would appreciate direction with this problem.

#Character String
x <- "I like 346 ice cream cones.  They're 99 percent good!  I ate 46."

#Replacement Values Dataframe
  symbol text                     
1 "346"  "three hundred forty six"
2 "99"   "ninety nine"            
3 "46"   "forty six" 

#replacement dataframe
numDF <- 
data.frame(symbol = c("346","99", "46"),
           text = c("three hundred forty six", "ninety nine","forty six"),
           stringsAsFactors = FALSE)

Desired outcome:

[1] "I like three hundred forty six ice cream cones.  They're ninety nine percent good!  You ate forty six?")

EDIT: I originally entitled this conditional gsub because that what it seems like to me even though there is no gsub involved.

r
Edit
Report

1 Answer

2

It wasn't exactly clear whether you really wanted to convert digits to their alpha equivalents. If so then here is a much more general strategy. There are (at least) two numeric to text conversion functions in the rhelp archives: Jim Lemon's digits2text and John Fox's numberstowords. I also switched over to gregexpr to get to a vectorized approach:

Cutting and pasting Lemon's function from the HTML found here worked out of the box:

>     m <- gregexpr("[0-9]+", x)
>     sym <- regmatches(x,m)
>     regmatches(x,m) <- digits2text(as.numeric(sym[[1]]))
illion = 0 
digilen = 3 
digitext = three hundred forty six 
[1] 6 4 3
> 
> x
[1] "I like three hundred forty six ice cream cones.  They're three hundred forty six percent good!  I ate three hundred forty six."

I needed to do some editing of the numberstowords because there were some missing linefeeds that messed up the parsing (and I include the successful version below this demonstration:

>     m <- gregexpr("[0-9]+", x)
>     sym <- regmatches(x,m)
>     regmatches(x,m) <- numbers2words(as.numeric(sym[[1]]))
> 
> x
[1] "I like three hundred forty six ice cream cones.  They're three hundred forty six percent good!  I ate three hundred forty six."

Fox's function edited from: http://tolstoy.newcastle.edu.au/R/help/05/04/2715.html

numbers2words <- function(x){

    helper <- function(x){

        digits <- rev(strsplit(as.character(x), "")[[1]])
        nDigits <- length(digits)
        if (nDigits == 1) as.vector(ones[digits])
        else if (nDigits == 2)
            if (x <= 19) as.vector(teens[digits[1]])
                else trim(paste(tens[digits[2]],
answered 2012-01-02T18:55:04.597

Your Answer