Given two data sets containing different pieces of information for an
overlapping set of addresses, you may be interested in merging your datasets by address.
Different data sources can represent the same address in very different
ways, so this can be a daunting task. This page aims to offer some data management
tips that will prevent errors and help in detecting true matches. We have included some code fragments and suggestions for
SAS procedures that are especially useful when working with addresses.
Data Management Tips
1. Separate the addresses into components (street number, street name, city,
state, zip). This can be made easier with the SAS functions scan,
substring, and the prx functions (prxparse, prxmatch,
prxsubstr, etc.). You may later combine them again into one variable, but cleaning and
formatting address components will be easier with separate variables.
In the dataset created below, the street number, street name, and street type
all appear in the variable address1 and city, state, and zip code all appear in
the variable address2. We use scan and substring here to separate
address1 into three component variables. For details on how to use
these functions, see
SAS’s online
documentation.
data test; length address1 $40. address2 $60.; input address1 $ 1-20 address2 $ 21-80; datalines; 1234 Washington St DC 12345 1234 Irving St Charlotte NC 12345 45 Wall street New York NY 90454 ; run; proc print data = test; run; Obs address1 address2 1 1234 Washington St DC 12345 2 1234 Irving St Charlotte NC 12345 3 45 Wall street New York NY 90454 data test; set test; streettype=scan(address1,-1); streetnum=scan(address1,1); streettype_start = index(address1, trim(streettype)); streetnum_end = length(streetnum); streetname = trim(substr(address1, streetnum_end+1, (streettype_start-streetnum_end-1))); drop streettype_start streetnum_end; run; proc print data = test; var streetnum streetname streettype; run; Obs streetnum streetname streettype 1 1234 Washington St 2 1234 Irving St 3 45 Wall street
If your data are less consistent, regular expressions may be the best
approach. For help with regular expressions in SAS, see our related code fragments page.
2. Within your string variables, trim leading and trailing spaces and check
that the variable length is not truncating any of the values. For help
with this, see SAS FAQ: How can I get rid of extra spaces in a string variable?.
If your strings have both capital and lowercase letters, use either the
upcase or lowcase function to force your string variables to be one
or the other. If you have a string variable that contains only digits (like the
variable streetnum in the above example), consider converting it to a
numeric variable to avoid worrying about spacing or formatting.
data test; set test; streetname_cap = upcase(streetname); streetnum_num = 1*streetnum; run;
3. Focus on the information in your data that is most meaningful in
matching records. There is likely information within an address that is redundant
and more difficult to match. For example, given a zip code, city and state are
redundant pieces of information that may be difficult to match due to different
spelling/spacing/capitalization patterns. In the example above,
streettype looks like it does not add information, but might complicate a
merge.
4. Test your code as you go. Start with a very small set of observations from
each dataset that includes some observations that you believe should match and
some that should not. Run your merge and see if it works they way you believe it
should. Use in = options
in your merge so that you can quickly see how many records are not being matched.
In the code below, we create a variable that indicates the outcome of the merge
for each observation.
data merged_data; merge address_A (in = A) address_B (in = B); by streetnum streetname zip; if A and not B then match = "A only"; if B and not A then match = "B only"; if A and B then match = "match"; run;
Common Issues to Look Out For
- Numbered streets that can be presented as numbers (2nd St., 5th Ave.) or
spelled out (Second St., Fifth Ave.). - Zip codes with leading zeroes (these occur in New England) that may or may
not appear. - Directions on streets (N. Taylor Rd., E. 154th St.).
- Fractions in addresses (332 1/2 Ashton Ave.).
- Different indications of apartments/condos/units/suites/floors in a given
building.
You may face all or none of the issues listed above. Most of them can be
addressed with the procedures presented in the code fragments or links shown
above.
Final Thoughts
Keep in
mind that matching on addresses is difficult under the best circumstances. Being realistic in your expectations
and knowing the quality of your data can allow
you to know when you have hit a reasonable match rate.