SoundexBR

CRAN Version Build Status License

Phonetic-Coding For Portuguese

The SoundexBR package provides an algorithm for decoding names into phonetic codes, as pronounced in Portuguese. The goal is for homophones to be encoded to the same representation so that they can be matched despite minor differences in spelling. The algorithm mainly encodes consonants; a vowel will not be encoded unless it is the first letter. The soundex code resultant consists of a four digits long string composed by one letter followed by three numerical digits: the letter is the first letter of the name, and the digits encode the remaining consonants. This R function may be useful for identifying “close” matches which typically fail due to variant spellings of names. For instance, both “Clair” and “Claire” return the same string “C460”, but the slightly different spellings of these names is enough to cause a deterministic linkage to fail when comparing the actual names.

The _ SoundexBR_ package lives on the R Foundation repository (CRAN) and is also hosted on Github. To install it, you can use the following methods.

1 - From the CRAN repository:

install.packages('SoundexBR',repos='http://cran.r-project.org')
require(SoundexBR)

2 - You can always download the latest development version using the nifty function from devtools package.

require(devtools)
install_github("danielmarcelino/SoundexBR")

3 - Or download the sources in a zip file and build manually. To do so, please unzip the file to an empty dir and run the following commands there:

R CMD build SoundexBR
R CMD INSTALL SoundexBR_*.tar.gz

If you’re running R on Windows, you need to install Rtools. Once you have installed Rtools, issue following command in command prompt:

R CMD build --binary <path to .tar.gz file>
R CMD INSTALL <path to .zip file>

Usage

A silly example:

names <- c('Ana Karolina Kuhnen', 'Ana Carolina Kuhnen', 'Ana Karolina',
'João Souza', 'João Souza', 'Dilma Vana Rousseff', 'Dilma Rousef','Aécio Neves', 'Aecio Neves')
    
soundexBR(names)
[1] "A526" "A526" "A526" "J220" "J220" "D451" "D456" "A251" "A251"
names2 <- c("HILBERT", "Heilbronn", "Gauss", "Kant")
 
 **Original Soundex:** 
 
 soundexBR(names2, BR=FALSE) 
[1] "H416" "H416" "G200" "K530"
 
 **SoundexBR:**

soundexBR(names2)
[1] "I416" "E416" "G200" "C530"

Example with RecordLinkage:

Some data:

data1 <- data.frame(list(
first_name=c('Ricardo','Maria','Tereza','Pedro','José','Germano'),
last_name=c('Cunha','Andrade','Silva','Soares','Silva','Lima'),
age=c(67,89,78,65,68,67),
birth=c(1945,1923,1934,1947,1944,1945),
date=c(20120907,20120703,20120301,20120805,20121004,20121209)
))
data2<-data.frame( list( first_name=c('Maria','Lúcia','Paulo','Marcos','Ricardo','Germânio'),
last_name=c('Andrada','Silva','Soares','Pereira','Cunha','Lima'),
age=c(67,88,78,60,67,80),
birth=c(1945,1924,1934,1952,1945,1932),
date=c(20121208,20121103,20120302,20120105,20120907,20121209)
))

Must call RecordLinkage package

> pairs<-compare.linkage(data1, data2,
 blockfld=list(c(1,2,4),c(1,2)),
 phonetic<-c(1,2), phonfun = soundexBR, strcmp = FALSE,
 strcmpfun<-jarowinkler, exclude=FALSE,identity1 = NA,
 identity2=NA, n_match <- NA, n_non_match = NA)
> print(pairs)
$data1
    first_name   last_name age birth     date
1 Ricardo   Cunha  67  1945 20120907
2   Maria Andrade  89  1923 20120703
3  Tereza   Silva  78  1934 20120301
4   Pedro  Soares  65  1947 20120805
5    José   Silva  68  1944 20121004
6 Germano    Lima  67  1945 20121209

$data2
     first_name   last_name age birth     date
1    Maria Andrada  67  1945 20121208
2    Lúcia   Silva  88  1924 20121103
3    Paulo  Soares  78  1934 20120302
4   Marcos Pereira  60  1952 20120105
5  Ricardo   Cunha  67  1945 20120907
6 Germânio    Lima  80  1932 20121209

$pairs
  id1 id2 first_name last_name age birth date is_match
1   1   5     1     1   1     1    1       NA
2   6   6     0     1   0     0    1       NA
3   2   1     1     0   0     0    0       NA

$frequencies
    first_name     last_name       age     birth      date 
0.1000000 0.1428571 0.1250000 0.1250000 0.1000000 

$type
[1] "linkage"

attr(,"class")
[1] "RecLinkData"

Editing correspondences

> editMatch(pairs)

Accessing information within the object:

> weights <- epiWeights(pairs, e = 0.01, f = pairs$frequencies)
> hist(weights$Wdata, plot = FALSE) # Plot TRUE
$breaks
[1] 0.2 0.4 0.6 0.8 1.0

$counts
[1] 2 0 0 1

$density
[1] 3.333333 0.000000 0.000000 1.666667

$mids
[1] 0.3 0.5 0.7 0.9

$xname
[1] "weights$Wdata"

$equidist
[1] TRUE

attr(,"class")
[1] "histogram"
> getPairs(pairs, max.weight = Inf, min.weight = -Inf)
  id    first_name last_name age birth     date Weight
1  1  Ricardo   Cunha  67  1945 20120907       
2  5  Ricardo   Cunha  67  1945 20120907   <NA>
3                                              
4  6  Germano    Lima  67  1945 20121209       
5  6 Germânio    Lima  80  1932 20121209   <NA>
6                                              
7  2    Maria Andrade  89  1923 20120703       
8  1    Maria Andrada  67  1945 20121208   <NA>

The Algorithm in a Nutshell

Capitalize all letters in the word and drop all punctuation marks. Pad the word with rightmost blanks as needed during each procedure step. Retain the first letter of the word. However, if the first letter of the word is H, retain the second letter. If the first letter of the word is Y, change to I. If the combination of the first and the second letters is: WA, change to VA. If the combination of the first and the second letters is: KA, change to CA. If the combination of the first and the second letters is: KO, change to CO. If the combination of the first and the second letters is: KU, change to CU. If the combination of the first and the second letters is: CI, change to SI. If the combination of the first and the second letters is: CE, change to SE. If the combination of the first and the second letters is: GE, change to JE. If the combination of the first and the second letters is: GI, change to JI.

Change all occurrence of the following letters to ‘0’ (zero):

A, E, I, O, U, H, W, Y.

Change letters from the following sets into the digit given:

1 = B, F, P, V

2 = C, G, J, K, Q, S, X, Z

3 = D,T

4 = L

5 = M,N

6 = R

Remove all pairs of digits which occur beside each other from the string that resulted after step (4). Remove all zeros from the string that results from step 5.0 (placed there in step 3) Pad the string that resulted from step (6) with trailing zeros and return only the first four positions, which will be of the form .