I'm trying to compare every element in a vector with every other.
From a dataframe of addresses, I extract streets for a zip code. And a vector of these street strings (like "123 main avenue"
) is the input.
streets <- c ("123 main avenue", "123 main ave", "456 paul st",
"456 paul street", "1 r parkway", "1 r pkwy")
I want to test for similarity of strings (like the one before with "123 main ave"
). I could use string distance on the substrings, but preferred grep.
I want to avoid the nested for
loop, but cannot think of anything better. Here's what I am trying to do:
compare = function(postal_code)
{
streets <- as.vector(props[props$Zip == postal_code,]["Street"])
cnt <- lengths(streets)[1][1]
#Assume two streets "123 main ave" and "123 main avenue"
for (i in 1:cnt)
{
for (j in 1:cnt)
{
prop1 = streets[[1]][i]
prop2 = streets[[1]][j]
#split "123 main avenue" into parts
prop1_parts = strsplit(trimws(prop1), ' ')
prop2_parts = strsplit(trimws(prop2), ' ')
prop1_parts_count = length(prop1_parts[[1]])
prop2_parts_count = length(prop2_parts[[1]])
#only if the parts of the two streets are equal
if (prop1_parts_count == prop2_parts_count)
{
#compare apples to apples: 123 with 123, main with main, and ave with avenue
for (x in 1:prop1_parts_count)
{
part1 = prop1_parts[[1]][x]
part2 = prop2_parts[[1]][x]
if (part1 == part2) { matched = matched & TRUE }
else {
#ignore number parts like 123
if (any(grep("[[:alpha:]]", part1)) & any(grep("[[:alpha:]]", part2))) {
#check if avenue is in ave or ave is in avenue
if (any(grep(part1, part2)) | any(grep(part2, part1))) {
matched = matched & TRUE
print(paste0(prop1, '-', prop2))
}
}
else {
matched = matched & FALSE
break #to pass to the next string
}
}
}
}
}
}
}
For a vector with 104 streets, the comparisons should be (104*103)/2; but with this code it is 104**2; and for these 10816 comparisons, the benchmark is:
I compiled the function as well but no improvement in the execution time.
Any elegant/quick way to improve this code is appreciated.
streets
: stackoverflow.com/q/6044112/2563804 \$\endgroup\$ – hplieninger Jul 24 '17 at 8:21