I'm new to R and have created a dictionary function. A user will input a phrase into a text field and the server will read it and see if there's a match in a back-end data table and if so, output the abbreviation of the phrase.
This dictionary data table does not have a 1 to 1 mapping. The dictionary has logical_word
and abbreviation
columns; here's a small sample:
238 abstract ABST NA NA NA
239 abstraction ABSTN NA NA NA
383 aggregate consumer economic ACE NA NA NA
876 business-to-consumer B2C NA NA NA
1309 consumer CNSMR NA NA NA
1310 Consumer Credit Counseling Service CCCS NA NA NA
1311 Consumer Indebtedness Index CII NA NA NA
1312 Consumer Lending CNL NA NA NA
1313 consumer loan application CLAPP NA NA NA
1314 consumer operating as business CSOAB NA NA NA
1315 Consumer Price Index
5582 time zone TZN NA NA NA
6041 Wholesale Consumer Information System WCIS NA NA NA
6119 zone ZONE NA NA NA
6121 ZORRO ZR NA NA NA
Suppose a user inputs "Consumer Credit Counseling Service zorro zone". This program will take the input and switch it to upper case and same w/dictionary DT.
I split the user input on whitespace into a vector, then run a loop and grep for the first word (CONSUMER
) to see if there's a match in the dictionary. If there is a match, then I keep going and grep for 2 words (CONSUMER CREDIT
). I do the same for all words until there's no match returned from the grep or if the match returned is == 1; in that case I pull the abbreviation value using merge()
and the phrase (searchStringDT[i])
.
When looking for "CONSUMER CREDIT COUNSELING SERVICE ZORRO"
the search result comes back as empty, so then I run a merge()
on the last iterated phrase "CONSUMER CREDIT COUNSELING SERVICE"
and the dictionary and get back the abbreviation "CCCS"
.
Then I set a flag (reset <- true
) and run the loop against "ZORRO"
and see if there's a match; since there is, I keep going and grep "ZORRO ZONE"
again. There's no value returned and I run a merge()
on "ZORRO"
and the dictionary and get back "ZR"
.
Then I run the loop on "ZONE"
, and since it's the last value, I run the merge()
and get back "ZONE"
.
I have a couple of questions:
Can someone recommend different approaches to improve speed/accuracy and make my code cleaner? Right now, it seems like a mess IMO.
If not, can someone recommend a way to fix my current approach, since this doesn't completely work.
In the grep I added
"^"
to make sure that I only return values that start with the user input, but when I tested with"abstract"
the grep returned both"abstract"
and"abstraction"
since the patterns match. My logic is based on only 1 value being returned to pull the abbreviation using themerge()
.If I add
"$"
to the grep then my code breaks since"CONSUMER CREDIT"
doesn't have an exact match. Is there some other condition I can add to see if the dictionary contains a phrase? So if I search"CONSUMER CREDIT"
I should get back"CONSUMER CREDIT COUNSELING SERVICE"
and if I search"ABSTRACT"
I should only get"ABSTRACT"
and not"ABSTRACTION"
?
The code:
searchDictionary <- function(userInput=NULL,dictionary=NULL){
userInput <- data.table(logical_word=userInput)
listTest <- data.frame(matrix(ncol = 5, nrow = nrow(userInput)))
names(listTest) <- c("logical_word","abbreviation","V3","V4","V5")
searchString <- ""
reset <- "FALSE"
searchStringDT <- data.table(matrix(ncol = 1, nrow = nrow(userInput)))
names(searchStringDT) <- c("logical_word")
i <- 1
while(i <= nrow(userInput)){
if(i==1){
searchString <- userInput[i]
searchStringDT$logical_word[i] <- unlist(searchString)
}
else if(reset == "TRUE"){
searchString <- userInput[i]
searchStringDT$logical_word[i] <- unlist(searchString)
}
else{
searchString <- paste(searchString,userInput[i])
searchStringDT$logical_word[i] <- unlist(searchString)
}
reset <- "FALSE"
searchResult <- dictionary[grep( paste0("^",searchStringDT[i]), dictionary$logical_word), ]
if(nrow(searchResult) == 0){
if( grepl("\\s", searchStringDT[i]) ){
listTest[i-1,] <- merge(searchStringDT[i-1], dictionary, "logical_word", all.x = TRUE, sort = FALSE)
i <- i
}
else{
listTest[i,] <- searchStringDT[i]
i <- i+1
}
reset <- "TRUE"
}
else if(nrow(searchResult) == 1){
listTest[i,] <- merge(searchStringDT[i], dictionary, "logical_word", all.x = TRUE, sort = FALSE)
i <- i+1
}
else{
i <-i+1
}
}
print("out for loop listTest")
print(listTest)
}
```